以下是一个完整的 C# 集合类(Collection)经典例程,演示了 List<T>Stack<T>Queue<T>Dictionary<TKey, TValue> 的基本用法。这些集合类是 .NET 中最常用的数据结构之一。

using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        // 1. List<T> 示例:动态数组,支持索引访问和随机插入/删除
        List<string> names = new List<string>();
        names.Add("Alice");
        names.Add("Bob");
        names.Insert(1, "Charlie"); // 在索引1处插入

        Console.WriteLine("List 内容:");
        foreach (string name in names)
        {
            Console.WriteLine(name);
        }

        Console.WriteLine();

        // 2. Stack<T> 示例:后进先出(LIFO)
        Stack<string> stack = new Stack<string>();
        stack.Push("Item1");
        stack.Push("Item2");
        stack.Push("Item3");

        Console.WriteLine("Stack 弹出顺序:");
        while (stack.Count > 0)
        {
            Console.WriteLine(stack.Pop());
        }

        Console.WriteLine();

        // 3. Queue<T> 示例:先进先出(FIFO)
        Queue<string> queue = new Queue<string>();
        queue.Enqueue("First");
        queue.Enqueue("Second");
        queue.Enqueue("Third");

        Console.WriteLine("Queue 弹出顺序:");
        while (queue.Count > 0)
        {
            Console.WriteLine(queue.Dequeue());
        }

        Console.WriteLine();

        // 4. Dictionary<TKey, TValue> 示例:键值对存储
        Dictionary<int, string> dictionary = new Dictionary<int, string>();
        dictionary.Add(1, "One");
        dictionary.Add(2, "Two");
        dictionary[3] = "Three"; // 使用索引器添加或更新

        Console.WriteLine("Dictionary 内容:");
        foreach (var kvp in dictionary)
        {
            Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
        }
    }
}

输出结果:

List 内容:
Alice
Charlie
Bob

Stack 弹出顺序:
Item3
Item2
Item1

Queue 弹出顺序:
First
Second
Third

Dictionary 内容:
Key: 1, Value: One
Key: 2, Value: Two
Key: 3, Value: Three

程序说明:

  1. List:用于存储一组可变长度的元素,支持通过索引访问,并允许在任意位置插入或删除元素。

  2. Stack:后进先出(LIFO)数据结构,适合需要按倒序处理数据的情况。

  3. Queue:先进先出(FIFO)数据结构,适用于任务调度等场景。

  4. Dictionary<TKey, TValue>:基于哈希表实现的键值对集合,可以快速查找与特定键关联的值。

以下是对 C# 中常用集合类(List<T>Stack<T>Queue<T>Dictionary<TKey, TValue>)的原理和内部实现机制的简要说明:

1. List(动态数组)

  • 原理
    List<T> 是基于数组的动态集合。它在底层使用一个 T[] 数组来存储数据,并且会根据需要自动扩展容量。

  • 插入/删除操作

    • 插入或删除元素时,如果超出当前数组容量,List<T> 会创建一个新的更大的数组(通常是当前容量的 2 倍),然后将原有元素复制到新数组中。

    • 删除元素不会减少数组大小,除非手动调用 TrimExcess()

  • 访问效率

    • 支持通过索引快速访问(时间复杂度为 O(1))。

    • 插入/删除元素在列表中间位置时效率较低(O(n)),因为需要移动后续元素。


2. Stack(栈结构)

  • 原理

    • Stack<T> 使用 List<T> 作为底层实现,但只暴露了符合“后进先出”(LIFO)规则的方法(如 PushPop)。

    • 栈的顶部元素始终是最后添加的元素。

  • 操作方式

    • Push(item):将元素压入栈顶。

    • Pop():移除并返回栈顶元素。

    • Peek():查看栈顶元素但不移除它。

  • 应用场景

    • 适用于需要回溯操作的场景,例如解析表达式、浏览器的前进/后退功能等。


3. Queue(队列结构)

  • 原理

    • Queue<T> 同样基于数组实现,支持“先进先出”(FIFO)规则。

    • 它维护两个指针:一个指向队首(front),另一个指向队尾(rear)。

  • 操作方式

    • Enqueue(item):将元素加入队列末尾。

    • Dequeue():移除并返回队列头部元素。

    • Peek():查看队列头部元素但不移除它。

  • 应用场景

    • 适用于任务调度、打印队列等需要顺序处理的场景。


4. Dictionary<TKey, TValue>(哈希表)

  • 原理

    • Dictionary<TKey, TValue> 使用哈希表(Hash Table)实现键值对存储。

    • 每个键通过哈希函数映射到一个桶(Bucket)中,用于快速查找对应的值。

  • 哈希冲突解决

    • 当不同键生成相同的哈希值时,Dictionary 会采用链表法或开放寻址法来解决冲突。

  • 性能特点

    • 查找、插入和删除的时间复杂度平均为 O(1),但在最坏情况下可能退化为 O(n)。

    • 如果键的分布不均或哈希函数设计不好,可能会导致性能下降。

  • 键的唯一性

    • 键必须是唯一的,不能重复。

    • 默认使用 EqualityComparer<TKey>.Default 来判断键是否相等。

更多推荐