C#常用数据结构栈的详细介绍
作者:王维志
定义
在C#中,Stack<T> 是一个后进先出(LIFO,Last-In-First-Out)集合类,位于System.Collections.Generic 命名空间中。Stack<T> 允许你将元素压入栈顶,并从栈顶弹出元素。
不难看出,最先放入栈中的元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除
即有泛型版本,又有非泛型版本,我们常用泛型版本(二者思想上差别不大,非泛型会涉及装箱拆箱),栈的结构如下
常规用法
1. 声明一个栈
无参构造函数
获取一个空的栈对象
public Stack(); Stack<int> stack = new Stack<int>();
接受一个可枚举对象
此构造函数允许你用一个已有的集合(如数组、列表等)来初始化栈,并按集合的顺序将元素压入栈中,集合的最后一个元素将成为栈的顶部。
public Stack(IEnumerable<T> collection); List<int> list = new List<int> { 1, 2, 3 }; Stack<int> stack = new Stack<int>(list);
不常用
指定栈的初始容量,减少扩展时的性能开销。这个参数不是常用的,因为栈会自动调整大小,但对于需要明确控制内存的场景,可以使用这个构造函数。
public Stack(int capacity); Stack<int> stack = new Stack<int>(100); // 初始化一个容量为100的栈
2. 将元素压入栈 (Push)
stack.Push(1); stack.Push(2); stack.Push(3);
3. 从栈顶弹出元素 (Pop)
Pop 会移除并返回栈顶的元素。 因为是后进先出,所以我们弹出的最后入栈的元素3 int topElement = stack.Pop(); // topElement is 3
4. 查看栈顶元素但不移除 (Peek)
Peek 只返回栈顶元素,但不会从栈中移除它。 int topElement = stack.Peek(); // topElement is 2
5. 检查栈是否为空 (Count 和 Any)
你可以使用 Count 属性或 Any 方法来检查栈中是否有元素。 bool isEmpty = stack.Count == 0; // or stack.Any() == false
6. 遍历栈中的元素
你可以通过 foreach 遍历栈中的元素,注意遍历的顺序是从栈顶到栈底。 foreach (var item in stack) { Console.WriteLine(item); }
7. 清空栈 (Clear)
你可以使用 Clear 方法来移除栈中的所有元素。 stack.Clear();
8.Contains 方法
判断栈中是否包含某个元素,返回 true 或 false。 bool exists = stack.Contains(2); // 检查栈中是否包含2
9.TryPeek 和 TryPop 方法
TryPeek(out T result) TryPeek 允许你尝试获取栈顶元素,而不会抛出异常。如果栈为空,它返回 false,否则返回 true 并输出栈顶元素。 if (stack.TryPeek(out int topElement)) { Console.WriteLine($"Top element: {topElement}"); } else { Console.WriteLine("Stack is empty"); }
TryPop(out T result) TryPop 允许你尝试弹出栈顶元素,同样不会抛出异常。如果栈为空,它返回 false,否则返回 true 并输出并移除栈顶元素。 if (stack.TryPop(out int poppedElement)) { Console.WriteLine($"Popped element: {poppedElement}"); } else { Console.WriteLine("Stack is empty"); }
使用频率较低的方法 10.TrimExcess 方法
TrimExcess 方法用于将内部存储的容量调整到栈中实际元素的数量。 栈动态调整大小时,可能会预留一些额外的空间。 此方法通过移除额外的空间来优化内存使用。 stack.TrimExcess(); // 移除多余的容量,减少内存浪费
11. CopyTo 方法
注意是一个浅拷贝方法
将栈中的元素复制到一个数组中,且从指定的数组索引位置开始放置。元素顺序是从栈顶到栈底. Stack<MyClass> stack = new Stack<MyClass>(); stack.Push(new MyClass { Value = 1 }); stack.Push(new MyClass { Value = 2 }); MyClass[] array = new MyClass[stack.Count]; //传入需要复制的数组,第二个参数是目标数组中开始复制的索引位置 //栈中的第一个元素会被复制到目标数组的该索引位置,后续的栈元素将按顺序依次复制到数组的后续位置。 stack.CopyTo(array, 0); // 修改数组中的对象 array[0].Value = 100; // 栈中的对象也会反映这个修改 Console.WriteLine(stack.Peek().Value); // 输出 100
12. ToArray 方法
注意是一个浅拷贝方法
将栈中的所有元素复制到一个新的数组中 会返回一个包含栈所有元素的新数组。栈中的元素会以 LIFO(后进先出)的顺序放入数组中, 也就是说,栈顶的元素会成为数组的第一个元素,栈底的元素会成为数组的最后一个元素。 Stack<int> stack = new Stack<int>(); stack.Push(1); stack.Push(2); stack.Push(3); int[] array = stack.ToArray(); foreach (var item in array) { Console.WriteLine(item); }
一个完整示例
using System; using System.Collections.Generic; class Program { static void Main() { // 创建一个栈 Stack<string> stack = new Stack<string>(); // 向栈中添加元素 stack.Push("First"); stack.Push("Second"); stack.Push("Third"); // 查看栈顶元素(不移除) Console.WriteLine("Peek: " + stack.Peek()); // 弹出栈顶元素 Console.WriteLine("Pop: " + stack.Pop()); // 再次查看栈顶元素 Console.WriteLine("Peek after pop: " + stack.Peek()); // 遍历栈 Console.WriteLine("Stack contents:"); foreach (var item in stack) { Console.WriteLine(item); } // 检查栈是否为空 Console.WriteLine("Is stack empty? " + (stack.Count == 0)); // 清空栈 stack.Clear(); Console.WriteLine("Stack cleared. Is stack empty? " + (stack.Count == 0)); } }
输出结果
Peek: Third
Pop: Third
Peek after pop: Second
Stack contents:
Second
First
Is stack empty? False
Stack cleared. Is stack empty? True
到此这篇关于C#常用数据结构栈的介绍的文章就介绍到这了,更多相关C#数据结构栈内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!