C#数据结构详解

C# 提供了丰富的数据结构集合,主要包含在 System.Collections 和 System.Collections.Generic 命名空间中。这些数据结构可以分为线性结构、非线性结构和特殊用途结构三大类。下面我将详细介绍 C# 中的主要数据结构及其使用场景。

一、线性数据结构

1. 数组 (Array)

​特点​​:

  • 固定大小
  • 连续内存分配
  • 支持随机访问

​示例​​:

// 一维数组
int[] numbers = new int[5] {1, 2, 3, 4, 5};

// 多维数组
int[,] matrix = new int[3, 3] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

// 数组操作
Console.WriteLine(numbers[0]); // 访问元素
Array.Sort(numbers); // 排序
Array.Reverse(numbers); // 反转

适用场景​​:

  • 数据量已知且固定
  • 需要频繁随机访问元素
  • 内存效率要求高

2. ArrayList (非泛型)

​特点​​:

  • 动态大小
  • 可以存储不同类型元素
  • 基于数组实现

​示例​​:

ArrayList list = new ArrayList();
list.Add(1);
list.Add("string");
list.Add(3.14);

// 需要类型转换
int first = (int)list[0];

注意​​:

  • 由于是非泛型集合,存在装箱/拆箱操作,性能较低
  • 现代C#开发中推荐使用泛型集合替代

3. List<T> (泛型)

​特点​​:

  • 动态大小
  • 类型安全
  • 基于数组实现

​示例​​:

List<int> numbers = new List<int>();
numbers.Add(1);
numbers.Add(2);
numbers.Add(3);

// 高效访问
int first = numbers[0];

// 其他操作
numbers.Remove(2);
numbers.Insert(1, 5);

适用场景​​:

  • 需要动态大小的集合
  • 需要类型安全
  • 需要频繁随机访问

4. LinkedList<T>

​特点​​:

  • 双向链表实现
  • 插入/删除操作高效(O(1))
  • 随机访问效率低(O(n))

​示例​​:

LinkedList<int> list = new LinkedList<int>();
list.AddLast(1);
list.AddLast(2);
list.AddLast(3);

// 插入操作
list.AddAfter(list.Find(2), 5);

// 遍历
foreach (var item in list)
{
    Console.WriteLine(item);
}

适用场景​​:

  • 需要频繁插入/删除操作
  • 不需要频繁随机访问
  • 实现队列或栈等数据结构

5. Queue<T> (队列)

​特点​​:

  • 先进先出(FIFO)结构
  • 基于链表实现

​示例​​:

Queue<string> queue = new Queue<string>();
queue.Enqueue("first");
queue.Enqueue("second");
queue.Enqueue("third");

// 出队
string first = queue.Dequeue();
string peek = queue.Peek(); // 查看但不移除

适用场景​​:

  • 任务调度
  • 消息队列
  • 需要按顺序处理的场景

6. Stack<T> (栈)

​特点​​:

  • 后进先出(LIFO)结构
  • 基于数组实现

​示例​​:

Stack<int> stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
stack.Push(3);

// 出栈
int top = stack.Pop();
int peek = stack.Peek(); // 查看但不移除

适用场景​​:

  • 函数调用栈
  • 表达式求值
  • 撤销操作实现

二、非线性数据结构

1. HashSet<T>

​特点​​:

  • 不允许重复元素
  • 无序集合
  • 基于哈希表实现

​示例​​:

HashSet<string> names = new HashSet<string>();
names.Add("Alice");
names.Add("Bob");
names.Add("Alice"); // 不会添加重复项

// 快速查找
bool contains = names.Contains("Bob");

适用场景​​:

  • 需要快速查找元素是否存在
  • 需要去重
  • 不关心元素顺序

2. SortedSet<T>

​特点​​:

  • 不允许重复元素
  • 自动排序
  • 基于平衡二叉搜索树实现

​示例​​:

SortedSet<int> numbers = new SortedSet<int>();
numbers.Add(3);
numbers.Add(1);
numbers.Add(2);

// 自动排序
foreach (var num in numbers)
{
    Console.WriteLine(num); // 输出1,2,3
}

适用场景​​:

  • 需要有序且不重复的集合
  • 需要范围查询

3. Dictionary<TKey, TValue>

​特点​​:

  • 键值对集合
  • 键唯一
  • 基于哈希表实现

​示例​​:

Dictionary<string, int> ages = new Dictionary<string, int>();
ages.Add("Alice", 25);
ages.Add("Bob", 30);

// 访问值
int aliceAge = ages["Alice"];

// 检查键是否存在
if (ages.ContainsKey("Charlie"))
{
    // ...
}

适用场景​​:

  • 需要快速键值查找
  • 实现映射关系
  • 缓存实现

4. SortedDictionary<TKey, TValue>

​特点​​:

  • 键值对集合
  • 键唯一且有序
  • 基于平衡二叉搜索树实现

​示例​​:

SortedDictionary<string, int> sortedAges = new SortedDictionary<string, int>();
sortedAges.Add("Bob", 30);
sortedAges.Add("Alice", 25);
sortedAges.Add("Charlie", 35);

// 按键排序输出
foreach (var pair in sortedAges)
{
    Console.WriteLine($"{pair.Key}: {pair.Value}");
}

适用场景​​:

  • 需要有序的键值对集合
  • 需要范围查询键

5. Hashtable (非泛型)

​特点​​:

  • 键值对集合
  • 键唯一
  • 基于哈希表实现
  • 非泛型,存在装箱/拆箱

​示例​​:

Hashtable table = new Hashtable();
table.Add("Alice", 25);
table.Add("Bob", 30);

// 需要类型转换
int aliceAge = (int)table["Alice"];

注意​​:

  • 现代C#开发中推荐使用泛型Dictionary替代

三、特殊用途数据结构

1. BitArray

​特点​​:

  • 位集合
  • 节省内存
  • 支持位运算

​示例​​:

BitArray bits = new BitArray(8); // 8位
bits[0] = true;
bits[1] = false;
bits[2] = true;

// 位运算
BitArray result = bits.And(new BitArray(8) { [0] = true, [1] = true, [2] = false });

适用场景​​:

  • 标志位集合
  • 节省内存的场景
  • 位运算操作

2. SortedList<TKey, TValue>

​特点​​:

  • 键值对集合
  • 键唯一且有序
  • 基于数组实现

​示例​​:

SortedList<string, int> sortedList = new SortedList<string, int>();
sortedList.Add("Bob", 30);
sortedList.Add("Alice", 25);
sortedList.Add("Charlie", 35);

// 按键排序输出
foreach (var pair in sortedList)
{
    Console.WriteLine($"{pair.Key}: {pair.Value}");
}

适用场景​​:

  • 需要有序键值对
  • 内存比SortedDictionary更高效
  • 插入/删除操作不频繁

四、性能比较与选择指南

数据结构插入/删除查找内存使用顺序性适用场景
ArrayO(n)O(1)有序固定大小集合
List<T>O(1)追加/O(n)插入O(1)索引/O(n)查找有序动态大小集合
LinkedList<T>O(1)O(n)有序频繁插入/删除
Queue<T>O(1)O(n)FIFO任务调度
Stack<T>O(1)O(n)LIFO撤销操作
HashSet<T>O(1)O(1)无序去重集合
SortedSet<T>O(log n)O(log n)有序有序去重集合
Dictionary<TKey,TValue>O(1)O(1)无序键值映射
SortedDictionary<TKey,TValue>O(log n)O(log n)有序有序键值映射
BitArrayO(1)O(1)极低有序位标志集合

五、实际应用示例

1. 使用Dictionary实现缓存

public class SimpleCache<TKey, TValue>
{
    private readonly Dictionary<TKey, TValue> _cache = new Dictionary<TKey, TValue>();
    
    public bool TryGetValue(TKey key, out TValue value)
    {
        return _cache.TryGetValue(key, out value);
    }
    
    public void Add(TKey key, TValue value)
    {
        _cache[key] = value;
    }
    
    public void Remove(TKey key)
    {
        _cache.Remove(key);
    }
}

2. 使用HashSet检测重复项

public bool HasDuplicates<T>(IEnumerable<T> items)
{
    var set = new HashSet<T>();
    foreach (var item in items)
    {
        if (!set.Add(item))
        {
            return true;
        }
    }
    return false;
}

3. 使用Queue实现广度优先搜索

public void BFS(Node startNode)
{
    var queue = new Queue<Node>();
    var visited = new HashSet<Node>();
    
    queue.Enqueue(startNode);
    visited.Add(startNode);
    
    while (queue.Count > 0)
    {
        var current = queue.Dequeue();
        ProcessNode(current);
        
        foreach (var neighbor in current.Neighbors)
        {
            if (!visited.Contains(neighbor))
            {
                visited.Add(neighbor);
                queue.Enqueue(neighbor);
            }
        }
    }
}

C# 提供了丰富的数据结构集合,每种数据结构都有其特定的优势和适用场景。选择合适的数据结构可以显著提高程序的性能和可维护性。在实际开发中:

  1. 优先考虑泛型集合(List<T>Dictionary<TKey,TValue>等),它们提供类型安全且性能更好
  2. 根据操作特点选择数据结构:
    • 需要快速查找:HashSet/Dictionary
    • 需要有序集合:SortedSet/SortedDictionary
    • 频繁插入/删除:LinkedList/Queue/Stack
  3. 注意内存使用情况,特别是处理大数据量时
  4. 考虑线程安全需求,必要时使用并发集合(ConcurrentQueueConcurrentDictionary等)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_shenbing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值