C# 堆栈推送和弹出示例

C# 中的 Stack 是什么?
堆栈是一种特殊情况的集合,代表了后进先出 (LIFO) 的概念。为了首先理解 LIFO,我们举个例子。想象一下一堆书,每本书都叠放在一起。
书籍的“后进先出”概念意味着只能从书堆中取出最上面的书。不能从中间取出一本书,因为那样会扰乱书堆的布局。
因此在 C#,堆栈也以相同的方式工作。元素被添加到堆栈中,一个元素位于另一个元素的顶部。将元素添加到堆栈的过程称为推送操作。要从堆栈中删除元素,也可以删除堆栈最顶部的元素。此操作称为弹出。
让我们更详细地了解 Stack 集合可用的操作。
堆栈的声明
堆栈是借助 Stack 数据类型创建的。关键字“new”用于创建 Stack 对象。然后将该对象分配给变量 st。
Stack st = new Stack()
将元素添加到堆栈
push 方法用于将元素添加到堆栈中。该语句的一般语法如下。
Stack.push(element)
从堆栈中删除元素
pop 方法用于从堆栈中删除元素。pop 操作将返回堆栈的最顶部元素。该语句的一般语法如下。
Stack.pop()
计数
此属性用于获取 Stack 中的项目数。以下是此语句的一般语法。
Stack.Count
包含
此方法用于查看元素是否存在于 Stack 中。以下是此语句的一般语法。如果元素存在,则该语句将返回 true,否则将返回值 false。
Stack.Contains(element)
现在让我们看看它在代码层面上的运作。下面提到的所有代码都将写入我们的 控制台应用。代码将被写入我们的 Program.cs 文件中。
在下面的程序中,我们将编写代码来了解如何使用上述方法。
示例 1:Stack.Push() 方法
在此示例中,我们将看到
- 如何创建堆栈。
- 如何显示堆栈的元素,并使用Count和Contain方法。
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoApplication { class Program { static void Main(string[] args) { Stack st = new Stack(); st.Push(1); st.Push(2); st.Push(3); foreach (Object obj in st) { Console.WriteLine(obj); } Console.WriteLine(); Console.WriteLine(); Console.WriteLine("The number of elements in the stack " +st.Count); Console.WriteLine("Does the stack contain the elements 3 "+st.Contains(3)); Console.ReadKey(); } } }
Code 解释:-
- 第一步是声明堆栈。这里我们将“st”声明为变量,用于保存堆栈的元素。
- 接下来,我们向堆栈添加 3 个元素。每个元素都通过 Push 方法添加。
- 现在,由于堆栈元素不能通过索引位置访问,就像 数组列表,我们需要使用不同的方法来显示堆栈的元素。对象 (obj) 是一个临时变量,它被声明用于保存堆栈的每个元素。然后我们使用 foreach 语句遍历堆栈的每个元素。对于每个堆栈元素,将值分配给 obj 变量。然后我们使用 Console.Writeline 命令将值显示到控制台。
- 我们正在使用 Count 属性(st.count) 获取堆栈中的项目数。此属性将返回一个数字。然后我们将该值显示到控制台。
- 然后我们使用 Contains 方法查看堆栈中是否存在值 3。这将返回 true 或 false 值。然后我们将此返回值显示到控制台。
如果正确输入上述代码并运行程序,将显示以下输出。
输出:
从输出中我们可以看到堆栈的元素被显示了出来。此外,还显示了 True 的值,表示值 3 在堆栈上被定义。
注意::您已经注意到,最后推送到堆栈的元素首先显示。这是堆栈的最顶部元素。堆栈元素的数量也显示在输出中。
示例 2:Stack.Pop() 方法
现在让我们看看“移除”功能。我们将看到从堆栈中删除最顶部元素所需的代码。
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoApplication { class Program { static void Main(string[] args) { Stack st = new Stack(); st.Push(1); st.Push(2); st.Push(3); st.Pop(); foreach (Object obj in st) { Console.WriteLine(obj); } Console.ReadKey(); } } }
Code 解释:-
- 这里我们只需发出用于从堆栈中删除元素的 pop 方法。
如果正确输入上述代码并运行程序,将显示以下输出。
输出:
我们可以看到元素 3 被从堆栈中移除。
C# Stack Peek() 方法
`Push` 和 `Pop` 方法操作的是栈顶元素,但有时你只需要查看栈顶元素而无需将其移除。`Peek` 方法正是为此而设计的。它会返回栈顶元素的值,同时保持集合不变,这在你想在决定弹出下一个元素之前先测试一下它时非常有用。
步骤1) 创建一个栈,并将三个元素压入其中,使值 3 位于栈顶。
步骤2) 调用 Peek 方法读取顶部元素,然后检查 Count 属性以确认没有删除任何元素。
using System; using System.Collections; namespace DemoApplication { class Program { static void Main(string[] args) { Stack st = new Stack(); st.Push(1); st.Push(2); st.Push(3); Console.WriteLine(st.Peek()); Console.WriteLine(st.Count); Console.ReadKey(); } } }
Code 解释:-
- 声明了一个名为 st 的栈,并使用 Push 方法将值 1、2 和 3 添加到栈中,因此 3 成为栈顶元素。
- Peek 方法返回顶部元素而不将其删除,Count 属性仍然报告堆栈中项目的完整数量。
程序运行时,它会打印出该值。 3 从 Peek 开始,然后是计数 3这证明该元素仍然在栈上。如果栈为空,Peek 会抛出 Invalid 异常。OperationException,因此在调用之前检查 Count 是安全的。
通用堆栈在 C# 中
以上示例使用了来自 System.Collections 的非泛型 Stack 类,该类将每个元素存储为一个对象。现代 C# 代码通常更倾向于使用泛型 Stack 类。这是 System.Collections.Generic 命名空间中的类。它将栈绑定到单个已声明的类型,因此编译器会检查每次 Push 和 Pop 操作,无需进行类型转换或装箱。
通用堆栈的主要优势下面列出。
- 型式安全: 类型在声明时就已确定,因此只能推送该类型的值,并且错误会在编译时被捕获。
- 禁止拳击: 像 int 这样的值类型直接存储,这样就避免了非泛型 Stack 所支付的装箱成本。
- 清洁器读取: Pop 和 Peek 直接返回声明的类型,因此您无需将结果从对象强制转换回来。
using System; using System.Collections.Generic; namespace DemoApplication { class Program { static void Main(string[] args) { Stack<string> st = new Stack<string>(); st.Push("Java"); st.Push("Python"); Console.WriteLine(st.Pop()); Console.ReadKey(); } } }
在这个例子中,栈被声明为 Stack因此,它只接受字符串值。Pop 方法直接返回一个字符串并打印出来。 Python最后一次推送的值。对于任何新项目,通用堆栈是推荐的选择。
C# 中栈和队列的区别
一叠和一个 队列 栈和队列都是控制元素移除顺序的集合,但它们遵循相反的规则。栈是后进先出(LIFO),而队列是先进先出(FIFO)。选择正确的集合可以让其他开发者清楚地理解你的代码意图。
主要区别如下:
- 订购: 栈先移除最近添加的元素(后进先出),而队列先移除最旧的元素(先进先出)。
- 方法: 栈使用 Push 和 Pop 来添加元素,而队列使用 Enqueue 来添加元素,使用 Dequeue 来移除元素。
- 顶层元素访问: 栈通过 Peek 函数读取下一个元素,队列通过从队首开始的 Peek 函数读取下一个元素。
- 典型用途: 栈适合撤销功能、表达式求值和递归 trac队列适合调度、缓冲和广度优先遍历。
这两种类型都可以以通用堆栈的形式提供。和队列在 System.Collections.Generic 中,因此无论选择哪种方式,都能获得类型安全。




