C# 堆栈(Stack)
在 C# 中,堆栈(Stack) 是一种后进先出(LIFO, Last In First Out)的数据结构。
堆栈(Stack)适用于存储和按顺序处理数据,其中最新添加的元素会最先被移除。
堆栈(Stack)代表了一个后进先出的对象集合。当您需要对各项进行后进先出的访问时,则使用堆栈。当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。
Stack 提供了两种实现方式:
- 非泛型
Stack
(System.Collections.Stack
):支持存储任何类型的对象(需要装箱和拆箱操作)。 - 泛型
Stack<T>
(System.Collections.Generic.Stack<T>
):支持强类型对象,避免装箱和拆箱,提高性能。
Stack 特性:
- 后进先出:最后压入堆栈的元素最先弹出。
- 动态大小:堆栈的容量根据需要动态调整。
- 泛型支持:通过
Stack<T>
提供类型安全,避免类型转换错误。 - 非线程安全:默认
Stack
和Stack<T>
都不是线程安全的。
Stack 类的方法和属性
下表列出了 Stack 类的一些常用的 属性:
属性名称 | 类型 | 描述 |
---|---|---|
Count | int | 获取堆栈中的元素个数。 |
SyncRoot | object | 获取一个对象,用于同步对堆栈的访问(非泛型)。 |
IsSynchronized | bool | 指示堆栈的访问是否同步(线程安全,始终为 false )。 |
下表列出了 Stack 类的一些常用的 方法:
方法名称 | 返回类型 | 描述 |
---|---|---|
元素操作 | ||
Push(object item) | void | 将元素压入堆栈的顶部。 |
Pop() | object | 移除并返回堆栈顶部的元素。 |
Peek() | object | 返回堆栈顶部的元素,但不移除。 |
Clear() | void | 移除堆栈中的所有元素。 |
检查与复制 | ||
Contains(object item) | bool | 确定某元素是否存在于堆栈中。 |
ToArray() | object[] | 将堆栈中的元素复制到新数组中(顺序翻转)。 |
Clone() | object | 创建当前堆栈的浅表副本。 |
CopyTo(Array array, int index) | void | 将堆栈中的元素复制到现有数组,从指定索引开始。 |
枚举器支持 | ||
GetEnumerator() | IEnumerator | 返回一个枚举器,用于循环访问堆栈中的元素。 |
线程安全 | ||
Synchronized(Stack stack) | Stack | 返回一个线程安全的堆栈包装器。 |
实例
下面的实例演示了堆栈(Stack)的使用。
非泛型堆栈:
实例
using System;
using System.Collections;
namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
Stack st = new Stack();
st.Push('A');
st.Push('M');
st.Push('G');
st.Push('W');
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
st.Push('V');
st.Push('H');
Console.WriteLine("The next poppable value in stack: {0}",
st.Peek());
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
Console.WriteLine("Removing values ");
st.Pop();
st.Pop();
st.Pop();
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
}
}
}
using System.Collections;
namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
Stack st = new Stack();
st.Push('A');
st.Push('M');
st.Push('G');
st.Push('W');
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
st.Push('V');
st.Push('H');
Console.WriteLine("The next poppable value in stack: {0}",
st.Peek());
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
Console.WriteLine("Removing values ");
st.Pop();
st.Pop();
st.Pop();
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
Current stack: W G M A The next poppable value in stack: H Current stack: H V W G M A Removing values Current stack: G M A
泛型堆栈:
实例
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Stack<int> stack = new Stack<int>();
// 压栈
stack.Push(10);
stack.Push(20);
stack.Push(30);
// 查看堆栈顶部
Console.WriteLine($"Peek: {stack.Peek()}"); // 输出:30
// 弹栈
Console.WriteLine($"Pop: {stack.Pop()}"); // 输出:30
// 剩余堆栈
Console.WriteLine("Remaining items:");
foreach (var item in stack)
{
Console.WriteLine(item); // 输出:20, 10
}
}
}
using System.Collections.Generic;
class Program
{
static void Main()
{
Stack<int> stack = new Stack<int>();
// 压栈
stack.Push(10);
stack.Push(20);
stack.Push(30);
// 查看堆栈顶部
Console.WriteLine($"Peek: {stack.Peek()}"); // 输出:30
// 弹栈
Console.WriteLine($"Pop: {stack.Pop()}"); // 输出:30
// 剩余堆栈
Console.WriteLine("Remaining items:");
foreach (var item in stack)
{
Console.WriteLine(item); // 输出:20, 10
}
}
}
Stack 与 Stack<T> 区别
Stack(非泛型)
- 存储对象为
object
类型。 - 使用时需要显式类型转换,可能会导致运行时异常。
Stack<T>(泛型)
- 提供类型安全,避免类型转换问题。
- 性能更优,因为避免了装箱和拆箱的开销。