VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 队列(Queue)与栈(Stack)

队列(Queue)与栈(Stack)
概述
队列和栈是两种经典的线性数据结构,核心区别在于元素的存取顺序:
队列(Queue):先进先出(FIFO,First-In-First-Out),类似排队买票,先到先得;
栈(Stack):后进先出(LIFO,Last-In-First-Out),类似叠盘子,最后放的先拿。
它们都是泛型集合(Queue、Stack),位于System.Collections.Generic命名空间,适合处理有序的线性操作场景。

  1. 队列(Queue):先进先出
    队列的核心操作是入队(Enqueue)和出队(Dequeue),支持查vb.net教程C#教程python教程SQL教程access 2010教程看队首元素(不移除),适合任务排队、消息调度等场景。
    1.1 实例代码:模拟打印机任务排队
    csharp
	using System;
	using System.Collections.Generic;
	
	class Program
	{
	static void Main()
	{
	// 1. 初始化队列:存储打印任务(字符串类型)
	Queue<string> printQueue = new Queue<string>();
	
	// 2. 入队:添加打印任务到队尾
	printQueue.Enqueue("报告.docx");
	printQueue.Enqueue("简历.pdf");
	printQueue.Enqueue("照片.png");
	
	// 3. 查看队首元素(不移除)
	string firstTask = printQueue.Peek();
	Console.WriteLine($"当前队首任务:{firstTask}"); // 输出:报告.docx
	
	// 4. 遍历队列(保持入队顺序)
	Console.WriteLine("
队列中的任务:");
	foreach (string task in printQueue)
	{
	Console.WriteLine($"- {task}"); // 输出:报告.docx、简历.pdf、照片.png
	}
	
	// 5. 出队:处理队首任务(移除并返回)
	string processedTask = printQueue.Dequeue();
	Console.WriteLine($"
已处理任务:{processedTask}"); // 输出:报告.docx
	
	// 6. 安全出队:避免空队列异常
	bool hasNext = printQueue.TryDequeue(out string nextTask);
	if (hasNext)
	{
	Console.WriteLine($"安全处理任务:{nextTask}"); // 输出:简历.pdf
	}
	
	// 7. 查看剩余任务数
	Console.WriteLine($"剩余任务数:{printQueue.Count}"); // 输出:1
	}
	}

1.2 逐行讲解
初始化:Queue printQueue = new Queue()创建存储字符串的队列,默认初始容量4,满了自动扩容;
入队:Enqueue将元素添加到队列末尾(类似排队尾);
查看队首:Peek获取队列第一个元素,但不改变队列状态;
遍历:foreach按入队顺序遍历(队列保持FIFO特性);
出队:Dequeue移除并返回队首元素(处理完任务就从队列删除);
安全出队:TryDequeue避免空队列抛出InvalidOperationException,返回是否成功,成功则通过out参数取元素;
任务数:Count属性获取当前队列元素数量。
1.3 基础知识拓展
内部实现
Queue基于循环数组实现:入队时在数组末尾添加,出队时从数组头部移除,满了则扩容(默认翻倍)。循环数组避免了每次出队时移动所有元素,效率更高(入队/出队均为O(1))。
线程安全
多线程场景下用ConcurrentQueue(System.Collections.Concurrent命名空间),支持并发入队/出队,无需手动加锁:
csharp

	ConcurrentQueue<string> safeQueue = new ConcurrentQueue<string>();
	safeQueue.Enqueue("任务1");
	bool success = safeQueue.TryDequeue(out string task);

适用场景
任务调度(如后台打印任务、异步任务队列);
消息队列(生产者-消费者模式);
广度优先搜索(BFS)算法。

  1. 栈(Stack):后进先出
    栈的核心操作是入栈(Push)和出栈(Pop),支持查看栈顶元素(不移除),适合撤销操作、表达式计算等场景。
    2.1 实例代码:模拟浏览器后退功能
    csharp
	using System;
	using System.Collections.Generic;
	
	class Program
	{
	static void Main()
	{
	// 1. 初始化栈:存储浏览历史(URL字符串)
	Stack<string> browserHistory = new Stack<string>();
	
	// 2. 入栈:添加最新浏览记录到栈顶
	browserHistory.Push("https://www.baidu.com");
	browserHistory.Push("https://www.github.com");
	browserHistory.Push("https://www.csdn.net");
	
	// 3. 查看栈顶元素(不移除)
	string currentPage = browserHistory.Peek();
	Console.WriteLine($"当前页面:{currentPage}"); // 输出:csdn.net
	
	// 4. 遍历栈:从栈顶到栈底(逆序入栈顺序)
	Console.WriteLine("
浏览历史(从新到旧):");
	foreach (string url in browserHistory)
	{
	Console.WriteLine($"- {url}"); // 输出:csdn、github、baidu
	}
	
	// 5. 出栈:后退到上一页(移除栈顶)
	string backPage = browserHistory.Pop();
	Console.WriteLine($"
后退离开:{backPage}"); // 输出:csdn.net
	Console.WriteLine($"当前页面:{browserHistory.Peek()}"); // 输出:github
	
	// 6. 安全出栈:避免空栈异常
	bool hasPrev = browserHistory.TryPop(out string prevPage);
	if (hasPrev)
	{
	Console.WriteLine($"安全后退到:{prevPage}"); // 输出:github
	Console.WriteLine($"当前页面:{browserHistory.Peek()}"); // 输出:baidu
	}
	
	// 7. 剩余记录数
	Console.WriteLine($"剩余历史数:{browserHistory.Count}"); // 输出:1
	}
	}

2.2 逐行讲解
初始化:Stack browserHistory = new Stack()创建存储URL的栈,默认初始容量4;
入栈:Push将元素添加到栈顶(最新记录在最上面);
查看栈顶:Peek获取栈顶元素(当前页面),不改变栈状态;
遍历:foreach按栈顶到栈底顺序遍历(因为栈是LIFO);
出栈:Pop移除并返回栈顶元素(后退操作,离开当前页面);
安全出栈:TryPop避免空栈抛出异常,返回是否成功;
记录数:Count获取剩余元素数量。
2.3 基础知识拓展
内部实现
Stack基于动态数组实现:入栈时在数组末尾添加元素,出栈时移除末尾元素(效率O(1)),满了自动扩容(默认翻倍)。
经典应用
撤销功能:如Word的Ctrl+Z,每一步操作入栈,撤销时出栈;
括号匹配:判断字符串"(())[]"是否合法,遇到左括号入栈,右括号则出栈匹配;
表达式求值:计算后缀表达式(如3 4 + 5 *),数字入栈,运算符则弹出两个数字计算后再入栈;
深度优先搜索(DFS):如二叉树遍历,用栈模拟递归。

3.队列与栈的对比

特性 队列(Queue 栈(Stack
存取顺序 先进先出(FIFO) 后进先出(LIFO)
核心操作 Enqueue/Dequeue Push/Pop
查看顶部元素 Peek(队首) Peek(栈顶)
遍历顺序 入队顺序 栈顶到栈底顺序
典型应用 任务排队、消息队列 撤销操作、括号匹配

总结
队列和栈是基础且实用的数据结构:
队列:按顺序处理场景,核心FIFO;
栈:逆序处理场景,核心LIFO;
两者均不支持随机访问,操作集中在“头部”(队首/栈顶);
优先使用泛型版本(Queue、Stack),类型安全且高效。
掌握这两种结构,能解决很多常见编程问题,比如任务调度、算法实现等。
(本节完)
下一章:泛型与集合进阶
(深入讲解泛型原理、自定义集合等内容)

本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49382.html


相关教程