首页/新闻资讯/正文详情

栈与队列:数据结构基础与应用实战

发布时间:2026/11/14 0:50:17 来源:云帆数科 栏目:资讯中心
栈与队列:数据结构基础与应用实战
1. 栈与队列程序世界的两种基础容器第一次接触栈和队列时我正试图理解为什么浏览器后退按钮总是能准确带我回到上一个页面。后来才发现这背后正是栈这种数据结构的典型应用。作为计算机科学中最基础的两种线性数据结构栈和队列就像是我们日常生活中使用的两种不同容器一个像叠放的盘子一个像排队的队伍。栈Stack遵循后进先出LIFO原则就像我们叠放盘子时最后放上去的盘子总是最先被取用。而队列Queue则遵循先进先出FIFO原则如同排队买票先来的人先得到服务。这两种看似简单的结构却支撑着从操作系统到网络协议栈的无数底层机制。在真实的开发场景中栈和队列的应用远比教科书上的例子丰富得多。函数调用栈管理着程序的执行流程浏览器的历史记录依赖栈的特性消息队列处理着分布式系统中的异步通信甚至连我们日常使用的撤销Undo功能背后都是栈在发挥作用。2. 栈的深度解析与实战应用2.1 栈的核心特性与实现方式栈的基本操作非常简单主要包括push入栈将元素添加到栈顶pop出栈移除并返回栈顶元素peek查看栈顶返回但不移除栈顶元素isEmpty判空检查栈是否为空用数组实现栈时我们需要维护一个指向栈顶的指针。以下是Java的实现示例public class ArrayStack { private int maxSize; private int[] stack; private int top -1; public ArrayStack(int size) { this.maxSize size; stack new int[maxSize]; } public void push(int value) { if (isFull()) { throw new RuntimeException(栈已满); } stack[top] value; } public int pop() { if (isEmpty()) { throw new RuntimeException(栈为空); } return stack[top--]; } public boolean isFull() { return top maxSize - 1; } public boolean isEmpty() { return top -1; } }在实际项目中直接使用语言提供的栈实现如Java的Stack类或Deque接口通常是更好的选择因为它们已经处理了线程安全等复杂问题。2.2 栈在表达式求值中的应用栈最经典的应用之一就是表达式求值。让我们以中缀表达式转后缀表达式为例假设有中缀表达式3 4 * 2 / (1 - 5)转换步骤初始化一个空栈用于存放运算符一个空列表用于输出从左到右扫描表达式遇到数字直接输出遇到左括号入栈遇到右括号则不断出栈直到遇到左括号遇到运算符时弹出栈顶优先级不低于当前运算符的所有运算符再将当前运算符入栈表达式扫描完毕后将栈中剩余运算符全部弹出按照这个算法上面的中缀表达式将转换为后缀表达式3 4 2 * 1 5 - / 实现这个算法的Python代码示例def infix_to_postfix(expression): precedence {:1, -:1, *:2, /:2, ^:3} stack [] output [] for char in expression: if char.isdigit(): output.append(char) elif char (: stack.append(char) elif char ): while stack and stack[-1] ! (: output.append(stack.pop()) stack.pop() # 弹出左括号 else: # 运算符 while (stack and stack[-1] ! ( and precedence[stack[-1]] precedence[char]): output.append(stack.pop()) stack.append(char) while stack: output.append(stack.pop()) return .join(output)提示在实际工程中处理表达式时还需要考虑数字可能有多位、有小数点和负数等情况上述代码做了简化处理。2.3 栈在算法问题中的妙用栈在解决某些算法问题时能发挥意想不到的作用。以有效的括号问题为例给定一个只包括 (, ), {, }, [, ] 的字符串判断字符串是否有效。有效需满足左括号必须用相同类型的右括号闭合左括号必须以正确的顺序闭合使用栈可以优雅地解决这个问题public boolean isValid(String s) { StackCharacter stack new Stack(); MapCharacter, Character map Map.of( ), (, }, {, ], [ ); for (char c : s.toCharArray()) { if (map.containsValue(c)) { stack.push(c); } else if (map.containsKey(c)) { if (stack.isEmpty() || stack.pop() ! map.get(c)) { return false; } } } return stack.isEmpty(); }另一个经典例子是单调栈用于解决下一个更大元素类问题。其核心思想是维护一个栈保持栈内元素单调递增或递减。3. 队列的全面剖析与应用场景3.1 队列的基本实现与变种队列的基本操作包括enqueue入队在队尾添加元素dequeue出队移除并返回队首元素front查看队首返回但不移除队首元素isEmpty判空检查队列是否为空用数组实现队列时需要注意处理假溢出问题即数组未满但因移动导致无法入队这时循环队列就派上用场了。以下是循环队列的Java实现public class CircularQueue { private int[] queue; private int front, rear, size; public CircularQueue(int k) { queue new int[k]; front 0; rear -1; size 0; } public boolean enQueue(int value) { if (isFull()) return false; rear (rear 1) % queue.length; queue[rear] value; size; return true; } public boolean deQueue() { if (isEmpty()) return false; front (front 1) % queue.length; size--; return true; } public int Front() { return isEmpty() ? -1 : queue[front]; } public int Rear() { return isEmpty() ? -1 : queue[rear]; } public boolean isEmpty() { return size 0; } public boolean isFull() { return size queue.length; } }3.2 队列在BFS算法中的应用广度优先搜索BFS是队列最典型的应用之一。以二叉树的层序遍历为例from collections import deque def levelOrder(root): if not root: return [] result [] queue deque([root]) while queue: level_size len(queue) current_level [] for _ in range(level_size): node queue.popleft() current_level.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) result.append(current_level) return resultBFS算法保证我们总是先访问离起点最近的节点这一特性使其在最短路径问题中非常有用。3.3 消息队列与生产消费模型在现代分布式系统中消息队列如RabbitMQ、Kafka发挥着至关重要的作用。它们本质上都是队列概念的延伸解决了以下问题解耦生产者和消费者缓冲流量峰值实现异步处理提高系统可扩展性以RabbitMQ为例创建一个简单的工作队列// 生产者 const amqp require(amqplib); async function sendMessage() { const connection await amqp.connect(amqp://localhost); const channel await connection.createChannel(); const queue task_queue; await channel.assertQueue(queue, { durable: true }); const msg process.argv.slice(2).join( ) || Hello World!; channel.sendToQueue(queue, Buffer.from(msg), { persistent: true }); console.log( [x] Sent %s, msg); setTimeout(() { connection.close(); process.exit(0) }, 500); } sendMessage(); // 消费者 async function receiveMessage() { const connection await amqp.connect(amqp://localhost); const channel await connection.createChannel(); const queue task_queue; await channel.assertQueue(queue, { durable: true }); channel.prefetch(1); // 每次只处理一个消息 console.log( [*] Waiting for messages in %s. To exit press CTRLC, queue); channel.consume(queue, msg { const secs msg.content.toString().split(.).length - 1; console.log( [x] Received %s, msg.content.toString()); setTimeout(() { console.log( [x] Done); channel.ack(msg); }, secs * 1000); }, { noAck: false }); } receiveMessage();注意在实际生产环境中需要处理连接失败、消息序列化、错误处理等更复杂的情况。4. 栈与队列的对比与进阶话题4.1 核心差异与选择标准虽然栈和队列都是线性数据结构但它们的操作顺序完全不同特性栈队列操作原则LIFO (后进先出)FIFO (先进先出)典型操作push, popenqueue, dequeue应用场景函数调用、撤销操作消息处理、BFS实现复杂度相对简单需要考虑循环等问题选择使用栈还是队列的关键在于问题的需求需要回退或最近相关的场景用栈需要公平或顺序处理的场景用队列4.2 双端队列Deque与优先队列双端队列Deque结合了栈和队列的特性允许在两端进行插入和删除操作。Java中的ArrayDeque就是基于数组实现的高效双端队列DequeString deque new ArrayDeque(); deque.addFirst(First); // 前端添加 deque.addLast(Last); // 后端添加 String first deque.removeFirst(); // 前端移除 String last deque.removeLast(); // 后端移除优先队列Priority Queue则是队列的变种元素按优先级出队而非插入顺序。它通常使用堆Heap实现PriorityQueueInteger pq new PriorityQueue(); pq.offer(5); pq.offer(1); pq.offer(3); while (!pq.isEmpty()) { System.out.println(pq.poll()); // 输出1, 3, 5 }4.3 多栈与多队列的协同工作在复杂系统中常常需要多个栈或队列协同工作。例如实现一个栈的O(1)最小值查询功能可以使用辅助栈class MinStack: def __init__(self): self.stack [] self.min_stack [] def push(self, x): self.stack.append(x) if not self.min_stack or x self.min_stack[-1]: self.min_stack.append(x) def pop(self): if self.stack.pop() self.min_stack[-1]: self.min_stack.pop() def top(self): return self.stack[-1] def getMin(self): return self.min_stack[-1]另一个例子是用队列实现栈虽然看似违反直觉但通过巧妙地使用两个队列可以实现class MyStack { private QueueInteger q1 new LinkedList(); private QueueInteger q2 new LinkedList(); private int top; public void push(int x) { q1.add(x); top x; } public int pop() { while (q1.size() 1) { top q1.remove(); q2.add(top); } int result q1.remove(); QueueInteger temp q1; q1 q2; q2 temp; return result; } }在实际工程中理解这些基础数据结构的本质比记住特定实现更重要。栈和队列的概念会以各种形式出现在系统设计的各个层面从CPU的指令流水线到操作系统的进程调度从网络协议的数据包处理到数据库的事务管理。

相关推荐

技术博客写作指南:从结构到SEO优化
技术博客写作指南:从结构到SEO优化

1. 为什么写博客这件事值得认真对待十年前我写下人生中第一篇博客时,完全没意识到这个简单的行为会成为职业生涯的转折点。那篇不到800字的技术笔记,不仅让我获得了第一份远程工作邀约,更意外构建起持续至今的专业人脉网络。在这个信息爆炸的… · 2026/11/3 0:23:20

北京家政养老融合服务:模式、需求与商业机会
北京家政养老融合服务:模式、需求与商业机会

1. 项目概述:家政与养老融合的市场机遇北京作为国内老龄化程度较高的超大型城市,其"家政养老"服务试点具有典型的样本意义。这种模式本质上是通过整合传统家政服务的灵活性与专业养老服务的标准化,构建覆盖生活照料、医疗护理、精神… · 2026/11/9 5:12:17

在Mac本地跑语音听写与LLM改写:Whisper+Ollama实战
在Mac本地跑语音听写与LLM改写:Whisper+Ollama实战

1. 为什么要在本地跑听写和改写把语音转文字和文本润色这两件事都放在本地完成,是 TalkScribe 这个项目最核心的出发点。我最早接触这类需求是在做访谈整理的时候,一段一小时的录音丢进在线服务,等转写、等排队、还要担心内容被上传到别人的服… · 2026/11/10 8:17:44

苏州复审电工证的地方哪里靠谱 电工证值不值得考
苏州复审电工证的地方哪里靠谱 电工证值不值得考

苏州复审电工证的地方哪里靠谱 电工证值不值得考 不知道去哪报名怕被中介坑?你不是一个人。现在电工证复审流程越来越规范,但“苏州复审电工证的地方”这一问题,仍然困扰着不少电工师傅,尤其是刚入行或者准备换证的朋友们。很多人担心自己走错路,被中介… · 2026/11/14 0:49:28

绵阳哪里考低压电工证2026河南最新政策怎么走
绵阳哪里考低压电工证2026河南最新政策怎么走

绵阳哪里考低压电工证2026河南最新政策怎么走 不知道去哪报名怕被中介坑?绵阳哪里考低压电工证成了很多电工从业者最关心的问题,尤其是2026年河南最新政策出台后,很多人对报考流程、机构选择以及考试内容都产生了疑问。如果你也在找靠谱的考试渠道… · 2026/11/14 0:49:28

海宁考电工证哪里考的通过率揭秘
海宁考电工证哪里考的通过率揭秘

海宁考电工证哪里考的通过率揭秘 急需特种作业证才能上岗找工作,这句话在电工行业已经不是秘密了。尤其在海宁,越来越多的建筑工地、制造业企业都要求应聘者必须持有低压电工证或高压电工证,否则连面试机会都没有。但你真的了解电工证到底 哪里考 、… · 2026/11/14 0:49:28

佛山电工证发放要多久 良心建议帮你避开交钱没证的坑
佛山电工证发放要多久 良心建议帮你避开交钱没证的坑

佛山电工证发放要多久 良心建议帮你避开交钱没证的坑 怕考不过白交培训费?别再被培训机构忽悠了,佛山电工证发放要多久,其实有明确流程,关键看你有没有选对机构。下面这些建议,是过来人总结的良心建议,帮你省心又省事。… · 2026/11/14 0:49:28

电工证过期了不知道怎么复审延期?考电工证要会哪些电路在哪考
电工证过期了不知道怎么复审延期?考电工证要会哪些电路在哪考

电工证过期了不知道怎么复审延期?考电工证要会哪些电路在哪考 证书过期了不知道怎么复审延期,这种事在商丘房建工程圈并不少见。很多人拿到电工证后,以为一劳永逸,结果几年后突然发现证书已经失效,既耽误项目又影响个人发展。其实,… · 2026/11/14 0:49:28

长治电工作业团队值不值得考?学历不高也能拿证
长治电工作业团队值不值得考?学历不高也能拿证

长治电工作业团队值不值得考?学历不高也能拿证 你是不是也担心自己学历不高,连电工作业证都报不了名?其实, 长治电工作业团队 的报考流程并不复杂,关键是要找对机构,掌握正确的方法。今天我就从 值不值得考… · 2026/11/14 0:48:28

电工证丢失还能补吗?千万别踩坑,丢了证等于失业
电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/13 22:30:50

电力电缆作业证直播报名入口与办理流程良心建议
电力电缆作业证直播报名入口与办理流程良心建议

电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/13 5:40:45

英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑

英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/12 23:27:43

有初级电工证怎么工作 2026河南最新政策怎么应对
有初级电工证怎么工作 2026河南最新政策怎么应对

有初级电工证怎么工作 2026河南最新政策怎么应对 之前考的证在外省能不能转过来?这个问题我每天被问上百次。2026年河南最新政策对证书跨省转移有了明确说明,特别是南阳市的从业者,需要特别关注。… · 2026/11/14 0:00:31

电工证过期了不知道怎么复审?考电工证自学书+官方报名入口全攻略
电工证过期了不知道怎么复审?考电工证自学书+官方报名入口全攻略

电工证过期了不知道怎么复审?考电工证自学书+官方报名入口全攻略 证书过期了不知道怎么复审延期?很多人遇到这种情况,要么是工作太忙没时间处理,要么是不知道具体流程,导致证书失效,影响工作和项目进展。其实复审并不难,关键是要找准官方报名入口,掌… · 2026/11/14 0:00:31

为什么要低压电工证实操考试考什么
为什么要低压电工证实操考试考什么

为什么低压电工证值不值得考?别再被中介骗了 你是不是也经常看到网上有人在问“低压电工证到底值不值得考”?或者在找报名点时,担心被中间人骗钱?这些问题,我懂,我也经历过。作为一名在应急管理行业摸爬滚打多年的从业者,我深知低压电工证不仅是一个从… · 2026/11/14 0:00:31

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/13 6:12:21

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/13 6:11:51

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/13 22:31:30

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码