在日常开发中,集合与数据结构是处理数据的基础工具。C# 提供了一系列强大而灵活的集合类型,帮助我们存储、访问和管理数据。这篇文章将带你了解 C# 中常用的数组、列表、字典、队列、栈、集合和链表的特性和用法。
1. 数组(Array)
数组 是一种定长的数据结构,用于存储相同类型的数据。数组的大小在创建时必须指定,并且一旦创建后无法更改大小。
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
// 访问数组元素
Console.WriteLine(numbers[0]); // 输出:1
// 修改数组元素
numbers[0] = 10;
Console.WriteLine(numbers[0]); // 输出:10
- 特点:数组的存储是连续的,索引访问速度非常快(O(1) 时间复杂度)。
- 缺点:大小固定,无法动态扩展。
数组适合用于需要知道数据大小的场景,并且访问速度非常关键的情况。
2. 列表(List<T>)
列表(List<T>) 是一种动态数组,它的大小可以在运行时根据需要自动调整。列表在 C# 中非常常用,因为它提供了更多的灵活性。
List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
// 添加元素
numbers.Add(6);
// 移除元素
numbers.Remove(3);
// 访问列表元素
Console.WriteLine(numbers[0]); // 输出:1
- 特点:支持动态调整大小,具有丰富的操作方法,如添加、删除、插入等。内部基于数组实现。
- 适用场景 :当你需要一个大小可变的集合时,
List<T>
是理想选择。
3. 字典(Dictionary<TKey, TValue>)
字典(Dictionary<TKey, TValue>) 是一种键值对集合,允许通过键快速访问值。字典中的键是唯一的,值可以重复。
Dictionary<string, int> ages = new Dictionary<string, int>()
{
{ "Alice", 25 },
{ "Bob", 30 }
};
// 通过键访问值
Console.WriteLine(ages["Alice"]); // 输出:25
// 添加键值对
ages["Charlie"] = 35;
// 移除键值对
ages.Remove("Bob");
- 特点:基于哈希表实现,提供 O(1) 时间复杂度的键值访问。
- 适用场景:需要根据唯一键快速查找值时,字典是最佳选择。
4. 队列与栈(Queue<T> 和 Stack<T>)
队列(Queue<T>) 是一种先进先出(FIFO)的数据结构。栈(Stack<T>) 则是后进先出(LIFO)的数据结构。
-
队列 的使用场景通常是处理排队、任务调度等操作。
Queue<string> queue = new Queue<string>();
queue.Enqueue("first");
queue.Enqueue("second");
Console.WriteLine(queue.Dequeue()); // 输出:first -
栈 的典型应用场景包括撤销操作、表达式求值等。
Stack<int> stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
Console.WriteLine(stack.Pop()); // 输出:2 -
特点:队列和栈都支持 O(1) 的入队/出队和入栈/出栈操作。
-
适用场景:队列适合需要按顺序处理的任务,栈适合需要倒序处理的场景。
5. 集合(HashSet<T> 和 SortedSet<T>)
集合 是一种不允许重复元素的数据结构。C# 提供了两种常用的集合类型:HashSet<T>
和 SortedSet<T>
。
-
HashSet<T>:基于哈希表实现,提供 O(1) 时间复杂度的插入、删除和查找操作。
HashSet<int> set = new HashSet<int>() { 1, 2, 3 };
set.Add(4);
Console.WriteLine(set.Contains(2)); // 输出:True -
SortedSet<T>:基于二叉树实现,元素按照自然顺序排序,提供 O(log n) 时间复杂度的操作。
SortedSet<int> sortedSet = new SortedSet<int>() { 3, 1, 2 };
foreach (int num in sortedSet)
{
Console.WriteLine(num); // 输出:1, 2, 3
} -
适用场景 :当需要确保元素唯一性时,
HashSet<T>
是首选;当需要元素有序存储时,SortedSet<T>
是理想选择。
6. 链表(LinkedList<T>)
链表 是一种通过节点连接的线性数据结构,每个节点包含一个值和一个指向下一个节点的指针。C# 中的 LinkedList<T>
是一个双向链表,允许在链表的头部或尾部快速添加和删除元素。
LinkedList<string> linkedList = new LinkedList<string>();
linkedList.AddLast("first");
linkedList.AddLast("second");
linkedList.AddFirst("zero");
foreach (var item in linkedList)
{
Console.WriteLine(item); // 输出:zero, first, second
}
- 特点:链表的插入和删除操作非常高效(O(1) 时间复杂度),但随机访问元素的效率较低(O(n) 时间复杂度)。
- 适用场景 :当频繁需要在集合头部或尾部插入或删除元素时,
LinkedList<T>
非常适合。
结论
C# 提供了丰富的集合与数据结构工具,可以处理各种类型的数据存储需求。了解每种数据结构的特点和适用场景,可以帮助我们在开发中做出最佳选择。
- 数组适合固定大小、快速索引访问的场景。
- 列表是大小可变的集合,灵活性强,应用广泛。
- 字典用于键值对存储,支持快速查找。
- 队列和栈分别适合顺序和倒序处理任务。
- 集合用于去重和有序存储。
- 链表适合频繁的插入和删除操作。
选择正确的数据结构不仅能提高代码的性能,还能让代码更加简洁高效。根据需求选择最合适的工具,是编写高效代码的关键。
这篇博客为你介绍了C#中常用的集合与数据结构,并通过示例代码展示了它们的使用方式。希望这篇文章能帮助你更好地理解和使用这些工具。如果你对某一部分内容有深入的需求,欢迎继续探讨!