数据结构(三)——栈和队列

一、栈和队列的定义和特点

栈:受约束的线性表,只允许栈顶元素入栈和出栈

对栈来说,表尾端称为栈顶,表头端称为栈底,不含元素的空表称为空栈

先进后出,后进先出

队列:受约束的线性表,只允许在队尾插入,在队头删除

先进先出,后进后出

二、栈的表示和操作的实现

1.顺序栈的表示:存储结构

#define MAXSIZE 100  //顺序栈存储空间的初始分配址
typedef struct{SElemType *base;  //栈底指针SElemType *top;  //栈顶指针int stacksize;  //栈可用的最大容址
}SqStack;

top指栈顶元素的后一个位置,栈空时top指向的索引定义为-1

S.top = = 0 时,栈空 

S.top == stacksize 时,栈满

2.顺序栈的操作

a.初始化

//初始化
Status InitStack(SqStack &S){//构造一个空栈SS.base = (SElemType*)malloc(MAXSIZE * sizeof(SElemType));if(!S.base) exit(OVERFLOW);  //存储分配失败,退出程序S.top = S.base;S.stacksize = MAXSIZE;return OK;
}

b.入栈

当 index = arr.length 时,用户要入栈,给用户抛出“栈已满”的异常(上图最右边的情况)

//入栈
Status Push(SqStack &S,SElemType e){//插入元素e为新的栈顶元素if(S.top - S.base >= S.stacksize) {  //栈满//追加存储空间S.base = (SElemType*)realloc(S.base,(S.stacksize+MAXSIZE) * sizeof(SElemType));if(!S.base){  //存储分配失败exit(OVERFLOW)  //退出程序}S.top = S.base + S.stacksize;S.stacksize += MAXSIZE;}*S.top ++ = e;return OK;
}

c.出栈

如果 index = 0 的时候,用户要弹栈,给用户抛出“栈为空”的异常(上图最右边的情况)

//出栈
Status Pop(SqStack &S,SElemType &e){//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERRORif(S.top == S.base){  //栈为空return ERROR;}e = * --S.top;return OK;
}

d.顺序取栈顶元素

//顺序取栈顶元素
Status GetTop(SqStack S,SElemType &e){//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERRORif(S.top == S.base){  //栈为空e = *(S.top - 1);  //top指向下面的位置即栈顶,然后指向e,即赋值给ereturn OK;}
}

三、循环队列的表示和操作的实现

1.循环队列的表示

在循环队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外,尚需附设两个指针 front 和 rear 分别指示队列头元素及队列尾元素的位置

初始化建立空队列时,令 front = rear = 0, 每当插入新的队列尾元素时,“尾指针增1”;每当删除队列头元素时,“头指针增1”。因此,在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置

我们发现,在队列满时和空队列时,头指针和尾指针都指向同一个元素,那么如何分辨队列满和空队列?

1、少用一个元素空间, 即队列空间大小为m时,有m-1个元素就认为是队满。这样判断队空的条件不变,良D当头、尾指针的值相同时, 则认为队空;而当尾指针在循环意义上加1后是等于头指针,则认为队满。队空的条件:Q.front ==Q.rear
队满的条件:(Q.rear+ 1)%MAXQSIZE == Q.front
入队:Q.rear=(Q.rear +1)% MAXQSIZE
出队:Q.front=(Q.front +1)% MAXQSIZE

当前元素个数:(Q.rear-Q.front+MAXQSIZE)% MAXQSIZE

如上图所示,当J7、J8、J9 进入队列后,(Q.rear+ 1)%MAXQSIZE 的值等于 Q.front,此时认为队满。

2、另设一个标志位以区别队列是“空”还是“满"

2.循环队列的操作

(1)定义存储结构

#define MAXSIZE 100 
typedef struct{QElemType *base;  //初始化的动态分配存储空间int front;  //头指针,若队列不空,指向队列头元素int rear;  //尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;

(2)初始化

//初始化
Status InitQueue(SqQueue &Q) {//构造一个空队列QQ.base = (QElemType *)malloc(MAXSIZE * sizeof(QElemType));if(!Q.base){exit(OVERFLOW);}Q.front = Q.rear = 0;return OK;
}

(3)求元素个数

//求元素个数
int QueueLength(SqQueue Q){//返回Q的元素个数return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}

(4)插入新元素

//插入新元素
Status EnQueue(SqQueue &Q,QElemType e){//插入元素e为Q的新的队尾元素//判断队列是否为空if((Q.rear + 1) % MAXSIZE == Q.front){return ERROR;}Q.base[Q.rear] = e;Q.rear = (Q.rear + 1) % MAXSIZE;return OK;
}

(5)删除元素

//删除元素
Status DeQueue(SqQueue %Q,QElemType &e){//若队列不空,则删除Q的对头元素,用e返回其值,并返回OK;否则返回ERRORif(Q.front == Q.rear){return ERROR;}e = Q.base[Q.front];Q.front = (Q.front + 1) % MAXSIZE;return OK;
}

四、总结与习题

栈是限定仅在表尾进行插入或删除的线性表,又称为后进先出的线性表。栈有两种存储表示,顺序表示(顺序栈)和链式表示(链栈)。栈的主要操作是进栈和出栈,对于顺序栈的进栈和出栈操作要注意判栈满或栈空。

队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端删除元素。队列也有两种存储表示顺序表示(循环队列)和链式表示(链队)

栈和队列的逻辑结构都和线性表一样,数据元素之间存在一对一的关系。

循环队列中少用一个元素判断队空或队满时:

队空的条件::Q.front == Q.rear

队满的条件:(Q.rear+1)%MAXQSIZE == Q.front

答案:C

答案:C

解释:栈是后进先出的线性表,一个栈的入栈序列是1,2,3,…,n,而输出序列的第一个元素为n,说明1,2,3,…,n一次性全部进栈,再进行输出,所以p1=n,p2=n-1,….pi=n-i+1

答案:D

解释:对于非循环队列,尾指针和头指针的差值便是队列的长度,而对于循环队列,差值可能为负数,所以需要将差值加上MAXSIZE(本题为n),然后与MAXSIZE(本题为n)求余,即(n+r-f)%n

答案:B (方法同第一题)

元素出队序列默认就是元素的入队序列

答案:C

解释:初始栈顶指针top为n+1,说明元素从数组向量的高端地址进栈,又因为元素存储在向量空间V[1...n]中,所以进栈时top指针先下移变为n,之后将元素x存储在V[n]

答案:A

解释:x=top->data将结点的值保存到x中,top=top->link栈顶指针指向栈顶下一结点,即摘除栈顶结点。

答案:D

解释:一般情况下只修改头指针,但是,当删除的是队列中最后一个元素时,队尾指针也丢失了,因此需对队尾指针重新赋值。

答案:D

解释:数组A[0...m]中共含有m+1个元素,故在求模运算时应除以m+1

答案:B

答案:C

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

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

相关文章

SQL Server 存储过程开发三层结构规范

以下是《SQL Server 存储过程开发三层结构规范》的正式文档结构,适用于企业级数据库应用开发场景,有助于团队协作、代码审查与自动化运维: 📘 SQL Server 存储过程开发三层结构规范 一、架构设计总览 三层结构简介 层级命名约定…

接上篇,解决FramePack启动报错:“httpx.ReadError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。“的问题

#工作记录 FramePack部署(从PyCharm解释器创建和使用开始)保姆级教程-CSDN博客 上篇我们记录到FramePack从克隆到启动调试的保姆级教程,关于启动时会报以下错误的问题,已作出解决: 报错摘录: (.venv) PS F…

ping_test_parallel.sh 并行网络扫描脚本

并行网络扫描脚本分析:提高网络探测效率 引言脚本概述核心代码分析颜色定义与初始化并行处理机制并行执行与进程控制结果处理与统计 技术亮点性能分析结论附录:完整脚本 引言 在网络管理和运维过程中,快速检测网段内主机的在线状态是一项常见…

leetcode 3342. 到达最后一个房间的最少时间 II 中等

有一个地窖,地窖中有 n x m 个房间,它们呈网格状排布。 给你一个大小为 n x m 的二维数组 moveTime ,其中 moveTime[i][j] 表示在这个时刻 以后 你才可以 开始 往这个房间 移动 。你在时刻 t 0 时从房间 (0, 0) 出发,每次可以移…

关于vue-office在vue3工程中的引用报错问题

在vue3项目工程中,根据vue-office文档在vue2中的引用: //引入VueOfficeDocx组件 相关样式import VueOfficeDocx from vue-office/docx;import vue-office/docx/lib/index.css; 报错信息: [plugin:vite:import-analysis] Failed to resolve …

【macOS常用快捷键】

以下是 macOS 最常用快捷键列表,按使用频率由高到低分类整理,涵盖日常操作、效率工具及系统控制,助你快速提升使用效率: 一、基础高频操作 快捷键功能说明Command C复制选中内容Command V粘贴Command X剪切Command Z撤销上一…

mdadm 报错: buffer overflow detected

最近跑 blktest (https://github.com/osandov/blktests) 时发现 md/001 的测试失败了 单独执行,最后定位到是 mdadm 命令报错: buffer overflow detected 这个 bug 目前已经修复: https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/commit/?id827e1870f3205…

查看jdk是否安装并且配置成功?(Android studio安装前的准备)

WinR输入cmd打开命令提示窗口 输入命令 java -version 回车显示如下:

STM32智能刷卡消费系统(uC/OS-III)

一、项目概述与开发背景 本系统是一款基于STM32微控制器的智能刷卡消费终端,集成RFID识别、OLED显示、Flash存储、蓝牙通信等核心模块。项目采用uC/OS-III实时操作系统实现多任务并发处理,适用于校园一卡通、企业食堂等小额支付场景。系统支持定额扣款、…

[人机交互]以用户为中心的交互设计

一.以用户为中心设计的两个特征 • 理解和指定产品的使用上下文 ,并用于指导设计 • 用户参与式开发 • 参与 评估研究 (第十 — 十四章) • 参与 设计过程 :用户作为合作设计人员 二.用户参与设计的重要性 ◦ 需求的获取主要来源…

Abaqus学习笔记

目录 Abaqus介绍 学习资源 ​编辑Abaqus/CAE abaqus下载安装 abaqus基本操作 Abaqus启动 新建模型 ​编辑 ​编辑修改界面背景 ​编辑​编辑结果信息的显示与否 ​编辑计算结果信息字体设置 ​编辑允许多绘图状态 单位量纲 视图操作 事前说明 ODB文件 本构关系…

论坛系统开发(0-1) (上 前置知识介绍)

前置知识 1. 软件的生命周期 生命周期: 对事物进行定义(描述) -> 创建 -> 使用 -> 销毁的过程 软件⽣命周期中以划分为可⾏性研究、需求分析、概要设计、详细设计、实现、组装(集成)测试、确认测试、使⽤、维护、退役10个阶段,如下图: a. 可…

架构师面试(三十七):监控系统架构模式

题目 监控是在产品生命周期的运维环节,能对产品的关键指标数据进行【实时跟踪】并对异常数据进行【实时报警】。 一句话描述,监控系统可以帮我们【主动预防和发现】业务系统中的问题。 我们常说,监控系统是 “粮草”,业务系统是…

【面试 · 二】JS个别重点整理

目录 数组方法 字符串方法 遍历 es6 构造函数及原型 原型链 this指向 修改 vue事件循环Event Loop FormData 数组方法 改变原数组:push、pop、shift、unshift、sort、splice、reverse不改变原属组:concat、join、map、forEach、filter、slice …

深度学习里程碑:AlexNet 架构解析与核心技术详解

内容摘要 本文深度解析2012年ILSVRC冠军模型AlexNet,全面阐述其在深度学习发展中的关键突破。从模型架构出发,详细解析卷积层、池化层、全连接层的数学原理,重点分析ReLU激活函数、LRN局部归一化、重叠池化等创新技术的数学表达与工程价值。…

第5章 深度学习和卷积神经网络

深度学习是人工智能的一种实现方法。本章我们将考察作为深度学习的代表的卷积神经网络的数学结构。 5-1小恶魔来讲解卷积神经网络的结构 深度学习是重叠了很多层的隐藏层(中间层)的神经网络。这样的神经网络使隐藏层具有一定的结构,从而更加…

JVM——JVM是怎么实现invokedynamic的?

JVM是怎么实现invokedynamic的? 在Java 7引入invokedynamic之前,Java虚拟机(JVM)在方法调用方面相对较为“僵化”。传统的Java方法调用主要依赖于invokestatic、invokespecial、invokevirtual和invokeinterface这四条指令&#x…

STM32教程:ADC原理及程序(基于STM32F103C8T6最小系统板标准库开发)*详细教程*

前言: 本文章介绍了STM32微控制器的ADC外设,介绍了ADC的底层原理以及基本结构,介绍了ADC有关的标准库函数,以及如何编写代码实现ADC对电位器电压的读取。 可以根据基本结构图来编写代码 大体流程: 1、开启RCC时钟(包括ADC和GPIO的时钟,另外ADCCLK的分频器,也需要配置…

2025年APP安全攻防指南:抵御DDoS与CC攻击的实战策略

2025年,随着AI技术与物联网设备的深度渗透,DDoS与CC攻击的复杂性和破坏性显著升级。攻击者通过伪造用户行为、劫持智能设备、利用协议漏洞等手段,对APP发起精准打击,导致服务瘫痪、用户流失甚至数据泄露。面对这一挑战&#xff0c…

STM32的定时器

定时器的介绍 介绍:STM32F103C8T6微控制器内部集成了多种类型的定时器,这些定时器在嵌入式系统中扮演着重要角色,用于计时、延时、事件触发以及PWM波形生成、脉冲捕获等应用。 *几种定时器(STM32F103系列)&#xff1…