栈和队列:数据结构中的基础与应用​

栈和队列:数据结构中的基础与应用

请添加图片描述

在计算机科学的领域中,数据结构犹如大厦的基石,支撑着各类复杂软件系统的构建。而栈和队列作为两种基础且重要的数据结构,以其独特的特性和广泛的应用,在程序设计的舞台上扮演着不可或缺的角色。

栈:“后进先出” 的存储容器

栈是一种特殊的线性表,其特殊性体现在操作的局限性上。它只允许在固定的一端进行数据的插入和删除操作,这一端被称为栈顶,另一端则是栈底 。这种操作限制使得栈呈现出 “先进后出”(LIFO,Last In First Out)的逻辑特性。在日常生活中,栈的身影随处可见。比如堆叠的盘子,我们总是先取用最后放上去的盘子;函数调用时,最后调用的函数会最先返回;在文档编辑软件中,撤销操作也是按照最近的修改最先被撤销的顺序进行 。

从实现方式来看,栈主要有顺序栈和链式栈两种。顺序栈基于顺序表实现,利用连续的内存空间来存储元素,并通过管理结构体记录栈的状态,如栈的总容量、栈顶下标等。链式栈则借助单链表实现,每个链表节点存储一个元素,同样有管理结构体来维护栈顶指针、当前元素个数以及栈容量限制等信息 。

以顺序栈的操作为例,初始化栈时,需要为存储元素的数组分配内存空间,并将栈顶下标初始化为 -1,表示空栈。入栈操作时,首先判断栈是否已满,若未满,则将栈顶下标加 1,然后在对应的数组位置存储新元素。出栈操作则先检查栈是否为空,若不为空,先获取栈顶元素,再将栈顶下标减 1 。相关代码实现如下:

// 顺序栈结构体
typedef struct node {DATA *stack; // 存储元素的数组首地址int size; // 栈的总容量int top; // 栈顶下标(初始为-1表示空栈)
}SeqStack;// 初始化栈
int sstack_init(SeqStack *s, int num) {s->data = (DATA *)calloc(num, sizeof(DATA));if(s->data == NULL) return -1;s->size = num;s->top = -1; return 0;
}// 数据入栈/压栈
int sstack_push(SeqStack *s, DATA data) {if(sstack_isfull(s)) return -1;s->top++; s->data[s->top] = data; return 0;
}// 数据出栈/弹栈
int sstack_pop(SeqStack *s, DATA *data) {if(sstack_isempty(s)) return -1;*data = s->data[s->top];s->top--;return 0;
}

栈的优点显著,操作简单高效,由于仅对栈顶进行操作,其时间复杂度为 O (1) 。并且,“后进先出” 的特性使其在处理对称性、嵌套性问题时得心应手。例如在表达式求值(中缀转后缀)和括号匹配检查中,栈能够有效地解决这些问题。然而,栈也存在一定的局限性,它只能直接访问栈顶元素,顺序栈还存在容量限制,而链式栈则有额外的指针开销 。

栈在实际应用中十分广泛。在函数调用过程中,系统会利用栈来保存函数调用的相关信息,如返回地址、局部变量等,确保函数能够正确地返回和执行 。在浏览器的前进后退功能中,同样运用了栈的原理,用户访问过的页面地址被依次压入栈中,通过对栈的操作实现前进和后退的功能 。

队列:“先进先出” 的有序序列

队列同样是一种特殊的线性表,它的特殊之处在于只能在固定的两端进行操作,一端用于插入元素,称为队尾;另一端用于删除元素,称为队头 。这种操作方式使得队列呈现出 “先进先出”(FIFO,First In First Out)的特性,与现实生活中的排队现象极为相似。例如在银行排队办理业务,先来的客户先接受服务;打印队列中,先提交的文档先被打印;消息队列里,先到达的消息先被处理 。

队列的存储实现主要有循环队列和链式队列。循环队列基于数组实现,通过巧妙的模运算实现了数组空间的循环利用。为了区分队空和队满的状态,通常会牺牲一个存储单元 。链式队列则借助链表节点存储元素,通过维护队头指针和队尾指针来管理队列 。

以循环队列的操作为例,初始化循环队列时,需要为存储数组分配内存空间,并将队头下标和队尾下标都初始化为 0 。入队操作时,先判断队列是否已满,若未满,则在队尾下标对应的数组位置存储新元素,然后更新队尾下标 。出队操作则先检查队列是否为空,若不为空,先获取队头元素,再更新队头下标 。相关代码实现如下:

// 循环队列结构体
typedef struct {DATA *data; // 存储数组int size; // 队列容量int front; // 队头下标(出队维护队头下标)int rear; // 队尾下标(入队维护队尾下标)
}SQueue;// 初始化循环队列
int squeue_init(SQueue *q, int size) {q->data = (DATA *)calloc(size, sizeof(DATA));if (q->data == NULL)return -1;q->size = size;q->front = q->rear = 0;return 0;
}// 元素入队
int squeue_enqueue(SQueue *q, DATA data) {if (squeue_isfull(q))return -1;q->data[q->rear] = data;q->rear = (q->rear + 1) % q->size; return 0;
}// 元素出队
int squeue_dequeue(SQueue *q, DATA *data) {if (squeue_isempty(q))return -1;*data = q->data[q->front];q->front = (q->front + 1) % q->size;return 0;
}

队列的优点在于 “先进先出” 的特性保证了操作的公平性,并且支持高效的队头和队尾操作 。循环队列在访问速度上具有优势,适合固定大小场景;链式队列则能动态扩容,适用于大小不确定的场景 。但队列也有其缺点,它只能直接访问队头和队尾元素,循环队列还存在固定容量限制 。

队列在众多领域有着广泛的应用。在任务调度中,如打印队列,能够按照任务提交的先后顺序依次执行任务 。在消息队列中,确保消息按照到达的先后顺序被处理,避免消息混乱 。在广度优先搜索(BFS)算法中,队列用于存储待访问的节点,保证了搜索的广度优先特性 。在缓冲池管理和多线程编程中的生产者 - 消费者模式中,队列也发挥着重要作用,实现了数据的有序传递和共享 。

乱 。在广度优先搜索(BFS)算法中,队列用于存储待访问的节点,保证了搜索的广度优先特性 。在缓冲池管理和多线程编程中的生产者 - 消费者模式中,队列也发挥着重要作用,实现了数据的有序传递和共享 。

栈和队列作为基础的数据结构,虽然看似简单,却蕴含着强大的功能和广泛的应用价值。它们为解决各种复杂的编程问题提供了有效的工具和思路,无论是在系统软件的底层实现,还是在应用软件的功能开发中,都占据着举足轻重的地位 。深入理解和熟练运用栈和队列,将为我们在计算机科学的道路上奠定坚实的基础 。

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

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

相关文章

服务端配置 CORS解决跨域问题的原理

服务端配置 CORS(跨域资源共享)的原理本质是 浏览器与服务器之间的安全协商机制。其核心在于服务器通过特定的 HTTP 响应头声明允许哪些外部源(Origin)访问资源,浏览器根据这些响应头决定是否放行跨域请求。以下是详细…

Unity笔记(五)知识补充——场景切换、退出游戏、鼠标隐藏锁定、随机数、委托

写在前面:写本系列(自用)的目的是回顾已经学过的知识、记录新学习的知识或是记录心得理解,方便自己以后快速复习,减少遗忘。主要是C#代码部分。十七、场景切换和退出游戏1、场景切换场景切换使用方法: SceneManager.LoadScene()&a…

用 Spring 思维快速上手 DDD——以 Kratos 为例的分层解读

用 Spring 思维理解 DDD —— 以 Kratos 为参照 ​ 在此前的学习工作中,使用的开发框架一直都是 SpringBoot,对 MVC 架构几乎是肌肉记忆:Controller 接请求,Service 写业务逻辑,Mapper 操作数据库,这套套路…

docspace|Linux|使用docker完全离线化部署onlyoffice之docspace文档协作系统(全网首发)

一、 前言 书接上回,Linux|实用工具|onlyoffice workspace使用docker快速部署(离线和定制化部署)-CSDN博客,如果是小公司或者比如某个项目组内部使用,那么,使用docspace这个文档协同系统是非常合适的&…

【教程】如何高效提取胡萝卜块根形态和颜色特征?

胡萝卜是全球不可或缺的健康食材和重要的经济作物, 从田间到餐桌,从鲜食到深加工,胡萝卜在现代人的饮食和健康中扮演着极其重要的角色,通过量化块根形态和色泽均匀性,可实现对高产优质胡萝卜品种的快速筛选。工具/材料…

Python初学者笔记第二十四期 -- (面向对象编程)

第33节课 面向对象编程 1. 面向对象编程基础 1.1 什么是面向对象编程面向过程:执行者 耗时 费力 结果也不一定完美 面向对象:指挥者 省时 省力 结果比较完美面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它使用"对象&…

Go 语言 里 `var`、`make`、`new`、`:=` 的区别

把 Go 语言 里 var、make、new、: 的区别彻底梳理一下。1️⃣ var 作用:声明变量(可以带初始值,也可以不带)。语法: var a int // 声明整型变量,默认值为 0 var b string // 默认值 ""…

计算机网络---IP(互联网协议)

一、IP协议概述 互联网协议(Internet Protocol,IP)是TCP/IP协议族的核心成员,位于OSI模型的网络层(第三层),负责将数据包从源主机传输到目标主机。它是一种无连接、不可靠的协议,提供…

DataFun联合开源AllData社区和开源Gravitino社区将在8月9日相聚数据治理峰会论坛

🔥🔥 AllData大数据产品是可定义数据中台,以数据平台为底座,以数据中台为桥梁,以机器学习平台为中层框架,以大模型应用为上游产品,提供全链路数字化解决方案。 ✨杭州奥零数据科技官网&#xff…

【工具】通用文档转换器 推荐 Markdown 转为 Word 或者 Pdf格式 可以批量或者通过代码调用

【工具】通用文档转换器 推荐 可以批量或者通过代码调用 通用文档转换器 https://github.com/jgm/pandoc/ Pandoc - index 下载地址 https://github.com/jgm/pandoc/releases 使用方法: 比如 Markdown 转为 Word 或者 Pdf格式 pandoc -s MANUAL.txt -o example29.docx …

【UEFI系列】Super IO

文章目录一、什么是Super IO二、Super IO的作用常见厂商三、逻辑设备控制如何访问SIO逻辑设备的配置寄存器具体配置数值四、硬件监控(hardware monitor)一、什么是Super IO Super Input/Output超级输入输出控制器。 通过LPC(low pin count&a…

飞算 JavaAI 2.0.0 测评:自然语言编程如何颠覆传统开发?

一、前言 在AI技术高速发展的今天,编程方式正在经历一场革命。传统的“手写代码”模式逐渐被AI辅助开发取代,而飞算JavaAI 2.0.0的推出,更是让自然语言编程成为现实。 作为一名长期使用Java开发的程序员,我决定深度体验飞算Java…

Dubbo + zk 微服务

一、安装zk注册中心 win版本:windows环境下安装zookeeper教程详解(单机版)-CSDN博客 linux版本: 二、服务提供方搭建 引入dubbo和zk依赖 提供接口 使用注解方式实现接口级注册到zk,而springcloud是将服务注册到注册…

聆思duomotai_ap sdk适配dooiRobot

一、说明 1、duomotai_ap介绍 duomotai_ap是一个针对多模态开发板(如 CSK6-MIX 开发板)的大模型 AI 开发套件 SDK,主要用于开发语音、视觉等多模态 AI 应用。 2、dooiRobot介绍 基于Doly 机器人的经典外观设计,采用聆思CSK6011A…

Photoshop软件打开WebP文件格的操作教程

Photoshop软件打开WebP文件格的操作教程,好吧,这是英文原版: Photoshop 23.2 原生支持 WebP 格式,无需插件即可打开、编辑和保存 WebP 文件。用户可通过“文件 > 另存为副本”选择 WebP 格式,调整无损/有损压缩及质…

【数据结构】——顺序表链表(超详细解析!!!)

目录一. 前言二. 顺序表1. 顺序表的特点2. 代码实现三. 链表1. 单向链表代码实现2.双向链表代码实现四. 顺序表与链表的区别总结一. 前言 顺序表和链表是最基础的两种线性表实现方式。它们各有特点,适用于不同的应用场景。本文将详细介绍这两种数据结构的实现原理、…

GitHub的简单使用方法----(4)

在安装完git之后,桌面右键会出现两个git的选项第一个gui打开是这样的用户界面分别是新建仓库,克隆仓库,打开已经存在的仓库。tips:Git Gui 默认只能操作本地仓库——它本质上是一个图形化的“本地 Git 客户端”。 它本身不内置“下载远程仓库…

蓝桥杯----大模板

在写大模板之前,先讲一个函System_Init(),用于系统初始化关闭所有LED与外设,关闭所有LED就是传入0xff数据打开锁存器,关闭外设就是传入0x00打开锁存器。现在所有底层已经提供给大家了,先提供最简单版本的大模板&#x…

科技写作改革我见:取消参考文献,以点读率取代引证率!

科技写作改革我见:综述应取消参考文献,学术成就评估以点读下载率取代参考文献引证率!李升伟 张君飞 韩若兰引言在当今信息爆炸的时代,科技写作作为知识传播的核心载体,其形式与评价体系正面临前所未有的挑战。传统…

【Altium designer】快速建立原理图工程的步骤

快速建立原理图工程的步骤产品规格书分析 整理产品需求,明确主控芯片、外围接口类型、总线频率、电源需求及隔离要求、PCB尺寸等关键信息。使用文本清单列出所有需求,确保无遗漏。硬件需求架构图绘制 根据需求说明书和收集的信息,使用VISIO绘…