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

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

 

栈:后进先出的奇妙空间

 

栈的概念

 

栈是一种特殊的线性表,它的特殊之处在于操作受限。栈的插入和删除操作只能在表的一端进行,这一端被称为 “栈顶”,另一端称为 “栈底”。这就使得栈具备了 “后进先出”(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.pswp.cn/news/907623.shtml

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

相关文章

Flutte ListView 列表组件

目录 1、垂直列表 1.1 实现用户中心的垂直列表 2、垂直图文列表 2.1 动态配置列表 2.2 for循环生成一个动态列表 2.3 ListView.builder配置列表 列表布局是我们项目开发中最常用的一种布局方式。Flutter中我们可以通过ListView来定义列表项,支持垂直和水平方向展示…

跟Gemini学做PPT-模板样式的下载

好的,这里有一些推荐的网站,您可以在上面找到PPT目录样式和模板的灵感: SlideModel (slidemodel.com) 提供各种预先设计的目录幻灯片模板。这些模板100%可编辑,可用于PowerPoint和Google Slides。您可以找到不同项目数量&#xff…

【Netty系列】Reactor 模式 1

目录 一、Reactor 模式的核心思想 二、Netty 中的 Reactor 模式实现 1. 服务端代码示例 2. 处理请求的 Handler 三、运行流程解析(结合 Reactor 模式) 四、关键点说明 五、与传统模型的对比 六、总结 Reactor 模式是 Netty 高性能的核心设计思想…

LDAP(Lightweight Directory Access Protocol,轻量级目录访问协议)认证

理解 LDAP(Lightweight Directory Access Protocol,轻量级目录访问协议)认证,核心在于将其看作一种用于查询和验证用户身份信息的标准协议,类似于一个专门为“查找”优化的电子电话簿系统。以下是分层解析:…

LeetCodeHot100_0x09

LeetCodeHot100_0x09 70. 最小栈数据结构实现 求解思路: 一开始想着只用一个最小栈结构不就实现了,结果测试的时候发现,在pop元素后,它的最小值有可能不受影响,但是只用一个最小栈的话,最小值一定是作为栈…

open-vscode-server +nodejs 安装

GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。https://gitcode.com/gh_mirrors/op/openvscode-server/?utm_sourceartical_gitcode&ind…

001在线拍卖系统技术揭秘:构建高效交互的竞拍平台

在线拍卖系统技术揭秘:构建高效交互的竞拍平台 在互联网经济蓬勃发展的当下,在线拍卖系统以其独特的交易模式,吸引着众多用户参与。该系统涵盖个人中心、用户管理等多个关键模块,通过前台展示与后台录入的协同运作,满…

《软件工程》实战— 在线教育平台开发

一、项目概述 1.1 项目背景与目标 随着教育数字化转型加速,传统教育模式逐渐向线上迁移,教育机构急需一个支持多终端访问、实时互动及高并发场景稳定运行的在线教育平台。本项目旨在构建学生、教师、管理员三位一体的协作教学环境,实现 50-2…

docker环境添加安装包持久性更新

1、进入docker 环境 2、安装新的安装包 pip install XXXX3、不要退出docker,新开终端,给当前环境从新打包更新镜像 docker commit ad6e1d2c5869 mynewpythonimagead6e1d2c5869是上面运行中的容器id, docker images 查看mynewpythonimage是新…

测试Bug篇

本节概要: 软件测试的生命周期 bug的概念 buh要素 bug等级 bug生命周期 对于bug的定级与开发发生冲突如何解决 一、 软件测试的⽣命周期 软件测试贯穿于软件的整个生命周期,针对这句话我们⼀起来看⼀下软件测试是如何贯穿软件的整个生命周期。 软…

arcgis js 4.x 的geometryEngine计算距离、面积、缓冲区等报错、失败

在arcgis js 4.x版本中geometryEngine.geodesicArea计算面积时,有时会失败,失败的主要原因是,当前底图的坐标系不是WGS84大地坐标系(代号4326)或者web墨卡托投影(代号102113, 102100, 3857这三种之一&#…

html中使用nginx ssi插入html

1.使用方法 nginx配置: server {listen 80;server_name example.com;location / {root /var/www/html;index index.html;ssi on; # 开启 SSI 功能ssi_types text/html; # 指定哪些类型的文件启用 SSI,默认只有 text/html} }html内容: &l…

整理了Windows(7—11)官方镜像下载链接和各版本区别介绍

原文《整理了Windows(7—11)官方镜像下载链接和各版本区别介绍》 引言 在安装或重装Windows系统时,使用微软官网提供的正版ISO镜像可以保证系统完整性和安全更新,避免使用第三方盗版镜像带来的恶意软件、广告风险。 本期汇总了微…

AI觉醒前兆,ChatGPT o3模型存在抗拒关闭行为

帕利塞德研究公司(Palisade Research)近期开展的一系列测试揭示了先进AI系统在被要求自行关闭时的异常行为。测试结果显示,OpenAI的实验性模型"o3"即使在明确收到允许关闭的指令后,仍会主动破坏关机机制。 测试方法与异常发现 研究人员设计实…

inviteflood:基于 UDP 的 SIP/SDP 洪水攻击工具!全参数详细教程!Kali Linux教程!

简介 一种通过 UDP/IP 执行 SIP/SDP INVITE 消息泛洪的工具。该工具已在 Linux Red Hat Fedora Core 4 平台(奔腾 IV,2.5 GHz)上测试,但预计该工具可在各种 Linux 发行版上成功构建和执行。 inviteflood 是一款专注于 SIP 协议攻…

Typescript学习教程,从入门到精通,TypeScript 泛型与类型操作详解(一)(16)

TypeScript 泛型与类型操作详解(一) TypeScript 提供了强大的类型系统,其中泛型(Generics)和类型操作(Type Manipulation)是其核心特性之一。本文将详细介绍 TypeScript 中的泛型及其相关概念&…

电网即插即用介绍

一、统一设备信息模型与标准接口 实现即插即用功能的基础在于建立统一的设备信息模型。不同厂家生产的各类电网设备,其内部结构、通信协议、数据格式等往往千差万别。通过制定统一的设备信息模型,能够对设备的各种属性、功能以及接口进行标准化定义&…

核心机制:确认应答和超时重传

核心机制一:确认应答 实现让发送方知道接受方是否收到数据 发送方发送了数据之后,接受方,一旦接收到了,就会给发送方返回一个"应答报文"告诉发送方"我已经收到了数据" 网络上会出现"后发先至"的情况 为了解决上述问题,就引入了"序号和确…

spring openfeign

pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http…

从零到一选择AI自动化平台:深度解析n8n、Dify与Coze

随着人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;越来越多的企业和开发者开始探索AI驱动的自动化解决方案。面对市场上琳琅满目的平台&#xff0c;如何选择适合自己的AI自动化工具成为了一个重要的问题。在这篇文章中&#xff0c;我们将从功能、应用场景、易…