栈与队列:数据结构的有序律动

news2025/6/5 9:38:09

在数据结构的舞台上,栈与队列宛如两位优雅的舞者,以独特的节奏演绎着数据的进出规则。它们虽不像顺序表与链表那般复杂多变,却有着令人着迷的简洁与实用,在众多程序场景中发挥着不可或缺的作用。今天,就让我们一同去探索栈与队列的奇妙世界,掌握它们的操作技巧,并领略它们在实际应用中的风采。

 

栈:后进先出的奇妙空间

 

栈的概念

 

栈是一种特殊的线性表,它的特殊之处在于操作受限。栈的插入和删除操作只能在表的一端进行,这一端被称为 “栈顶”,另一端称为 “栈底”。这就使得栈具备了 “后进先出”(Last In First Out,LIFO)的特点,就像一个装满盘子的摞柱,最后放上去的盘子总是最先被取下来。

 

栈的基本操作

 

- 入栈(Push) :将一个元素插入到栈顶位置。如果栈已满,则无法继续入栈,这种情况称为 “栈溢出”。

- 出栈(Pop) :将栈顶元素移除。若栈为空时执行出栈操作,则会引发 “空栈” 错误。

- 获取栈顶元素(Top) :查看栈顶元素的值,但不将其移出栈。

 

栈的应用场景

 

- 括号匹配检测 :在编写代码或处理数学表达式时,括号的正确匹配至关重要。栈能轻松应对这一问题。例如,当我们遇到一个左括号时,将其入栈;当遇到右括号时,检查栈顶是否为对应的左括号,若是则出栈,否则说明括号不匹配。通过这种方式,我们可以精准判断括号序列是否合法。

- 递归函数的实现 :递归本质上是函数自己调用自己,在这个过程中,系统会使用一个隐式的栈来保存函数的调用信息,包括参数、返回地址等。这个栈就是 “调用栈”。每当一个递归函数调用自身时,相关信息就会被压入栈中;当函数执行完毕返回时,信息从栈中弹出,从而保证了程序能够正确地回到上一层调用的位置并继续执行。

 

栈的代码实现(以 Python 为例)

python

class Stack:

    def __init__(self):

        self.items = []

 

    def is_empty(self):

        return len(self.items) == 0

 

    def push(self, item):

        self.items.append(item)

 

    def pop(self):

        if self.is_empty():

            raise IndexError("栈为空,无法出栈")

        return self.items.pop()

 

    def top(self):

        if self.is_empty():

            raise IndexError("栈为空,无栈顶元素")

        return self.items[-1]

 

队列:先进先出的有序行进

 

队列的概念

 

队列同样是特殊的线性表,但它的操作规则与栈截然不同。队列的插入操作只能在一端(称为 “队尾”)进行,删除操作只能在另一端(称为 “队头”)进行。这种操作规则使得队列呈现出 “先进先出”(First In First Out,FIFO)的特性,就像生活中的排队场景,先来的人先接受服务,后来的人排在队伍末尾等待。

 

队列的基本操作

 

- 入队(Enqueue) :将一个元素添加到队尾。若队列已满,则无法继续入队。

- 出队(Dequeue) :将队头元素移除。若队列为空时执行出队操作,则会引发错误。

- 获取队头元素(Front) :查看队头元素的值,但不将其移出队列。

- 获取队尾元素(Rear) :查看队尾元素的值。

 

队列的应用场景

 

- 任务调度模拟 :在操作系统中,多个任务常常需要共享有限的资源,如 CPU。队列可用于模拟任务的调度过程。任务按照提交的先后顺序进入队列,等待 CPU 的分配。每当 CPU 完成一个任务,就从队列中取出下一个任务进行处理,确保了任务的公平调度。

- 缓冲区管理 :在数据传输过程中,如网络通信或文件读写,队列可充当缓冲区的角色。数据以队列的形式暂存,发送方将数据依次写入队尾,接收方从队头依次读取数据,使得数据的发送速度和接收速度能够协调一致,避免数据丢失或阻塞。

 

队列的代码实现(以 Python 为例)

python

class Queue:

    def __init__(self):

        self.items = []

 

    def is_empty(self):

        return len(self.items) == 0

 

    def enqueue(self, item):

        self.items.append(item)

 

    def dequeue(self):

        if self.is_empty():

            raise IndexError("队列为空,无法出队")

        return self.items.pop(0)

 

    def front(self):

        if self.is_empty():

            raise IndexError("队列为空,无队头元素")

        return self.items[0]

 

    def rear(self):

        if self.is_empty():

            raise IndexError("队列为空,无队尾元素")

        return self.items[-1]

 

栈与队列的专项练习

 

栈的练习

 

  1. 括号匹配验证 :编写一个函数,判断一个包含多种括号(如圆括号、方括号、大括号)的字符串是否匹配。例如,"({[]})" 是匹配的,而 "({[})]" 是不匹配的。

     - 思路:利用栈的后进先出特性,遇到左括号入栈,遇到右括号则检查栈顶是否为对应的左括号。若匹配则出栈,否则返回不匹配。遍历完整个字符串后,若栈为空则说明括号全部匹配。

 

  2. 递归函数改写 :将一个递归计算斐波那契数列的函数改写为非递归形式,借助栈来模拟递归过程。

     - 思路:在递归中,每次函数调用会保存当前的参数和返回地址。用栈来手动保存这些信息,通过循环逐步处理栈中的元素,模拟递归的调用过程,最终得到斐波那契数。

 

队列的练习

 

  1. 模拟超市收银 :假设超市有多个收银台,顾客按照到达时间进入队列,每个收银台每次只能为一个顾客服务。编写程序模拟顾客排队和收银的过程,计算每个顾客的等待时间和服务完成时间。

     - 思路:使用一个队列来存储等待的顾客,按照到达时间依次入队。为每个收银台设置一个服务队列,当收银台空闲时,从主队列中取出顾客并将其分配到服务队列中。记录每个顾客进入队列、开始服务和结束服务的时间,从而计算等待时间。

 

  2. 生产者 - 消费者问题 :模拟生产者和消费者之间的关系。生产者生产产品并放入缓冲区队列,消费者从缓冲区队列中取出产品进行消费。要求实现生产者和消费者之间的同步,避免缓冲区溢出或消费者取空缓冲区。

     - 思路:利用队列作为缓冲区。生产者在生产产品后尝试将其入队,如果队列已满则等待。消费者在消费前检查队列是否为空,如果为空则等待。通过引入锁和条件变量等同步机制,确保生产者和消费者对队列的操作是线程安全的。

 

总结与交流

 

通过学习栈和队列的概念、操作以及应用场景,我们对这两种数据结构有了较为全面且深入的理解,并通过代码实现和专项练习进一步巩固了知识。栈以其后进先出的特点在括号匹配、递归等问题中大显身手,而队列凭借先进先出的规则在任务调度、缓冲区管理等场景中发挥着关键作用。

 

现在,我想邀请大家在评论区分享自己对栈和队列的见解,或是你在学习和实践中遇到的有趣问题与解决方案。有没有在解决括号匹配问题时发现一些独特的技巧?或者在模拟任务调度时遇到了什么挑战?让我们共同交流、探讨,让知识在互动中不断深化,一起在这条数据结构与算法的学习之路上砥砺前行!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2397371.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初识PS(Photoshop)

初识PS(Photoshop) 1、Photoshop界面 2、常用快捷键

go语言的GMP(基础)

1.概念梳理 1.1线程 通常语义中的线程,指的是内核级线程,核心点如下: (1)是操作系统最小调度单元; (2)创建、销毁、调度交由内核完成,cpu 需完成用户态与内核态间的切…

电路图识图基础知识-高、低压供配电系统电气系统的继电自动装置(十三)

电气系统的继电自动装置 在供电系统中为保证系统的可靠性,保证重要负荷的不间断供电,常采用自动重合闸装置和备用电源自动投入装置。 1 自动重合闸装置 供配电系统多年运行实践表明,架空线路发生的故障多属于暂时性故障,如雷击…

Qt实现的水波进度条和温度进度条

一.效果 二.原理 1.水波 要模拟波浪,就要首先画出一条波浪线,正弦余弦曲线就很适合。 y=A*sin(ω*x+φ)+k y=A*cos(ω*x+φ)+k 这是正弦余弦曲线的公式,要想实现水波效果,那需要两条曲线,一条曲线的波峰对着另外一条曲线的波谷,要实现这样的曲线效果,只有让正弦曲线前移…

WEBSTORM前端 —— 第3章:移动 Web —— 第4节:移动适配-VM

目录 一、适配方案 二、VM布局 ​编辑 三、vh布局 四、案例—酷我音乐 一、适配方案 二、VM布局 三、vh布局 四、案例—酷我音乐

【Zephyr 系列 3】多线程与调度机制:让你的 MCU 同时干多件事

好的,下面是Zephyr 系列第 3 篇:聚焦 多线程与调度机制的实践应用,继续面向你这样的 Ubuntu + 真板实战开发者,代码清晰、讲解通俗、结构规范,符合 CSDN 高质量博客标准。 🧠关键词:Zephyr、线程调度、k_thread、k_sleep、RTOS、BluePill 📌适合人群:想从裸机开发进…

Kotlin-特殊类型

文章目录 数据类型枚举类型匿名类和伴生对象单例类伴生对象 数据类型 声明一个数据类非常简单: //在class前面添加data关键字表示为一个数据类 data class Student(var name: String, var age: Int)数据类声明后,编译器会根据主构造函数中声明的所有属性自动为其生成以下函数…

nssctf第二题[SWPUCTF 2021 新生赛]简简单单的逻辑

这是题目&#xff0c;下载后得到一个python文件,打开 解读代码&#xff1a; for i in range(len(list)):key (list[i]>>4)((list[i] & 0xf)<<4)result str(hex(ord(flag[i])^key))[2:].zfill(2)list[i]>>4&#xff1a;从列表中取数字同时高4位向右位…

《Discuz! X3.5开发从入门到生态共建》第3章 Discuz! X3.5 核心目录结构解析-优雅草卓伊凡

《Discuz! X3.5开发从入门到生态共建》第3章 Discuz! X3.5 核心目录结构解析-优雅草卓伊凡 3.1 系统核心目录结构 Discuz! X3.5采用模块化设计&#xff0c;主要目录结构如下&#xff1a; discuz_root/ ├─ api/ // API接口目录 ├─ config/ …

【HarmonyOS 5】鸿蒙应用实现发票扫描、文档扫描输出PDF图片或者表格的功能

【HarmonyOS 5】鸿蒙应用实现发票扫描、文档扫描输出PDF图片或者表格的功能 一、前言 图(1-1) HarmonyOS 系统提供的核心场景化视觉服务,旨在帮助开发者快速实现移动端文档数字化功能。 其核心能力包括:扫描合同、票据、会议记录并保存为 PDF 分享。拍摄课堂 PPT、书籍章…

Python_day43

DAY 43 复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 关于 Dataset 从谷歌图片中抓取了 1000 多张猫和狗的图片。问题陈述是构建一个模型&#xff0c;该模型可以尽可能准确地在图像…

STM32CubeDAC及DMA配置

STM32CubeDAC及DMA配置 一&#xff0c;问题1二&#xff0c;解决11&#xff0c;宏观思路CubeMX配置2&#xff0c;HAL_TIM_Base_Start(&htim6) 的作用1&#xff0c;作用1&#xff1a;使能TIM6的时钟并让它开始计数2&#xff0c;作用2&#xff1a;当 TIM6 溢出时&#xff0c;会…

行业案例 | OPPO借助Azure AI Speech国际服务实现音频文件智能转录

OPPO是全球领先的智能终端与移动互联网服务提供商&#xff0c;业务覆盖50余国&#xff0c;通过超40万销售网点和2500个服务中心与全球用户共享科技。作为软硬服一体化科技公司&#xff0c;OPPO以ColorOS为核心优化软件平台&#xff0c;为4.4亿月活用户打造智能操作系统&#xf…

基于 OpenCV 和 DLib 实现面部特征调整(眼间距、鼻子、嘴巴)

摘 要 本文介绍如何利用Dlib面部特征点检测和OpenCV图像处理技术&#xff0c;通过Python实现面部特征的精准调整。我们将以改变眼间距为例&#xff0c;演示包括地标检测、三角剖分变形等关键技术&#xff0c;该方法可扩展至嘴唇、眉毛等面部特征的调整。 技术栈 Python 3.8 …

spring-boot接入websocket教程以及常见问题解决

我们使用spring-boot接入websocket有三种方式&#xff1a;使用EnableWebSocket、EnableWebSocketMessageBroker以及ServerEndpoint&#xff0c;本文主要介绍使用ServerEndpoint方式的流程以及碰到的问题解决 接入方式 添加依赖 确保spring-boot-starter-websocket依赖 <d…

迈向分布式智能:解析MCP到A2A的通信范式迁移

智能体与外部世界的桥梁之言&#xff1a; 在深入探讨智能体之间的协作机制之前&#xff0c;我们有必要先厘清一个更基础的问题&#xff1a;**单个智能体如何与外部世界建立连接&#xff1f;** 这就引出了我们此前介绍过的 **MCP&#xff08;Model Context Protocol&…

深度学习|pytorch基本运算-hadamard积、点积和矩阵乘法

【1】引言 pytorch对张量的基本运算和线性代数课堂的教学有一些区别&#xff0c;至少存在hadamard积、点积和矩阵乘法三种截然不同的计算方法。 【2】hadamard积 hadamard积是元素对位相乘&#xff0c;用“*”连接张量&#xff0c;代码&#xff1a; # 导入包 import torch …

FFmpeg移植教程(linux平台)

目录 第三方源码编译三部曲关于 configure 的说明 FFmpeg 移植流程获取源码方法一&#xff1a;git 远程克隆方法二&#xff1a;官网下载压缩包解压 配置安装 第三方源码编译三部曲 Linux平台下有许多开源的第三方库和服务&#xff0c;这些开源代码一般都符合GNU-autotools编码…

Mybatis:灵活掌控SQL艺术

在前面的文章中&#xff0c;小编分享了spring中相关的知识&#xff0c;但是没有分享到&#xff0c;如何去更高效操作数据库。 操作数据库传统的方法就是通过JDBC来进行操作。 这个传统方法使用上可谓是够麻烦的 1.首先创建一个数据源对象 2.设置该数据源的属性&#xff08;…

2025.05.28【Choropleth】群体进化学专用图:区域数据可视化

Load geospatial data Start by loading your geospatial data in R, and build a basic plot. Data from the package The cartography comes with a set of geospatial data included. Learn how to use it to build a choropleth map. 文章目录 Load geospatial dataData …