Skip to main content

堆栈(Stack)

在 C# 中,堆栈(Stack) 是一种后进先出(LIFO, Last In First Out)的数据结构。

堆栈(Stack)适用于存储和按顺序处理数据,其中最新添加的元素会最先被移除。

堆栈(Stack)代表了一个后进先出的对象集合。当您需要对各项进行后进先出的访问时,则使用堆栈。当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。

Stack 提供了两种实现方式:

  1. 非泛型 StackSystem.Collections.Stack):支持存储任何类型的对象(需要装箱和拆箱操作)。
  2. 泛型 Stack<T>System.Collections.Generic.Stack<T>):支持强类型对象,避免装箱和拆箱,提高性能。

Stack 特性:

  • 后进先出:最后压入堆栈的元素最先弹出。
  • 动态大小:堆栈的容量根据需要动态调整。
  • 泛型支持:通过 Stack<T> 提供类型安全,避免类型转换错误。
  • 非线程安全:默认 StackStack<T> 都不是线程安全的。

Stack 类的方法和属性

下表列出了 Stack 类的一些常用的 属性

属性名称类型描述
Countint获取堆栈中的元素个数。
SyncRootobject获取一个对象,用于同步对堆栈的访问(非泛型)。
IsSynchronizedbool指示堆栈的访问是否同步(线程安全,始终为 false)。

td>获取 Stack 中包含的元素个数。

下表列出了 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 + " ");
}
}
}
}

当上面的代码被编译和执行时,它会产生下列结果:

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
}
}
}

Stack 与 Stack<T> 区别

Stack(非泛型)

  • 存储对象为 object 类型。
  • 使用时需要显式类型转换,可能会导致运行时异常。

Stack<T>(泛型)

  • 提供类型安全,避免类型转换问题。
  • 性能更优,因为避免了装箱和拆箱的开销。