数据结构--栈和队列

本文详细介绍了栈和队列的概念,它们作为线性表的特殊形式,具有后进先出(LIFO)和先进先出(FIFO)的特点。栈主要用于表达式求解、递归等场景,队列则常见于任务调度。文章讨论了栈和队列的顺序存储和链式存储结构,包括基本操作的实现,如入栈、出栈、入队、出队,并探讨了递归的定义、优缺点以及如何将递归转换为非递归。同时,还解决了队列中的假上溢问题,提出了循环队列的解决方案。
摘要由CSDN通过智能技术生成

栈和队列

定义和特点

在这里插入图片描述
栈和队列都是线性表,是插入和删除位置受限制的线性表

栈的特点是后进先出,表现在代码上就是:插入只能从最后插入,删除只能从最后删除
队列的特点是先进先出,表现在代码上就是:插入只能从最后插入,删除只能从前面删除

在这里插入图片描述
在这里插入图片描述

案例引入

在这里插入图片描述
在这里插入图片描述
后进先出,实现倒序

在这里插入图片描述
先入栈的后匹配
在这里插入图片描述
在这里插入图片描述
利用栈的特点,可以实现表达式优先级的设置

在这里插入图片描述

定义和特点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
栈顶正在准备指引a3加入

在这里插入图片描述
可以在入栈时穿插出栈,就可以达到不同的效果,但是不可能有cba这种情况,因为c要想先出来,那么ab就要先进去,那么最后只能cba顺序

栈与一般线性表的不同
在这里插入图片描述

栈的表示

在这里插入图片描述
抽象数据类型的定义

其中 基本操作包括:
在这里插入图片描述

栈的实现–顺序存储结构

表示

在这里插入图片描述
top指针真正指向的是栈顶元素之上的地址,方便后续操作
stacksize可表示栈可使用的最大容量

在这里插入图片描述
在这里插入图片描述

基本操作的实现

初始化

在这里插入图片描述
注意 同一个数组中的指针相减,得到的是两个指针所指元素相差的元素个数,也就相当于下标相减
在这里插入图片描述
首先定义一个栈的数据 封装成一个结构体
在这里插入图片描述
这里S是结构体的具体对象,之后的操作都是利用S来调用数据,

S.base=new …
该行的意思是分配一个MAXSIZE长度的数组空间(c++语法)

注意,指针和数组,可以看成一回事

判断栈是否为空

在这里插入图片描述

求顺序栈长度

在这里插入图片描述

清空顺序栈

在这里插入图片描述
直接将top指针指向base指针即可,因为哪怕定义空顺序栈时,我们也不知道每个元素的内容是否为空,随机分配闲置的地址而已

销毁顺序栈

在这里插入图片描述

顺序栈的入栈

在这里插入图片描述

顺序栈的出栈

在这里插入图片描述
对于图中简化代码部分,–S.top是每回合将top指针下移,前面有个*,是调用下移后的指针

栈的实现–链式存储结构

表示

在这里插入图片描述
头指针直接指向栈顶结点
并且没有头结点

左边代码最后一行与上面几行结构体的定义无关,而是创建了一个类的对象S,并且是以指针形式,创建了一个指针S
注意,头指针的名字就可以是链栈的名字,也就是,S可以说是此链栈,也可以说是该链栈的头指针

基本操作的实现

初始化

在这里插入图片描述
指针置空,等待插入结点

判断链表是否为空

在这里插入图片描述
如果头指针还处于置空状态,那么就是空链栈

链栈的入栈

在这里插入图片描述
注意最后要将p指针赋值给s指针,不然就把链栈修改了(因为头指针被改,那么链栈的名字也就是改变了,也就是链表被改了)

链栈的出栈

在这里插入图片描述

取栈顶元素

在这里插入图片描述

栈与递归

定义

在这里插入图片描述

思想

在这里插入图片描述
递归就是分治的思想 将一个复杂的问题 不断进行简化
简化一个不可解决的复杂的问题,最终简化到可以解决的问题(这个就是递归的出口)

在这里插入图片描述
简化一个复杂的问题 不断简化直到简化到可以解决的问题 这个可以解决的问题就是基本项 也就是递归的出口
而不断简化的过程 就是归纳项

在这里插入图片描述
在这里插入图片描述
因为递归的特点也是 先调用的后返回 所以 符合栈的特点
在这里插入图片描述
递归在结束之前 栈中会有函数的记录 保留着尚未返回值的函数的地址 等待函数返回值

递归的优缺点

在这里插入图片描述

递归转为非递归

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(在时间要求苛刻的情况下转为非递归 否则不要转)

队列

定义和特点

在这里插入图片描述

在这里插入图片描述

表示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里头尾指针只是逻辑命名,实际上就是两个整数,用来表示操作元素的下标

顺序存储结构的实现与操作

基本操作的实现(顺序表)

入队与出队

在这里插入图片描述
入队:直接移动”代指针“(用整数变量来表示数组下表从而发挥类似于指针的作用)来插入元素,并将尾指针移动到下一个位置待命
出队:直接移动“代指针”来丢弃元素,移动头指针丢掉元素

队列的小问题----假上溢

在这里插入图片描述
这样,一个队列,只能用满一次,存在假溢出问题

解决方案:利用取余运算,实现循环使用
在这里插入图片描述
对指针加一之后的数进行取余:%(maxsize),这样,就可以将指针从头开始循环,
因为rear+1 是正常操作 但是想要让指针可以循环使用 那么直接对这个结果取模即可 这样 rear+1的最后位置 就是循环后的位置 (可以想象在上面复制了好几份队列并接在一起 )

具体操作如下

在这里插入图片描述

区别队空与队满

在这里插入图片描述
队空与队满都是front==rear 因为当队满的时候 rear本应该在队最尾端的上面 但是循环处理之后 rear就会来到队首 与front重合

解决方案
在这里插入图片描述
我们就规定,剩余一个元素不使用,当有n-1个元素时,就认为,队列已满,这样,队满的判断条件就与队空区别开来

判断队满时 仍然需要取模 因为现在是在循环的前提下 所以要考虑到循环状态下 rear下一个位置是front 取模就是设置成循环状态(不取模就不是循环状态 rear+1就是线性状态)

初始化

在这里插入图片描述
在这里插入图片描述

求队列长度

在这里插入图片描述
尾指针减去头指针再加上maxqsize 最后括上括号 对 maxqsize取余

循环队列入队

在这里插入图片描述

循环队列出队

在这里插入图片描述

取队头元素

在这里插入图片描述

链式存储结构的实现与操作(带有头结点)

表示

在这里插入图片描述
左边定义的是结点元素的结构,右边定义的是一条链表的结构,注意,链表结构定义的是非指针类型,所以调用的时候,用“.”来调用

基本操作的实现
初始化

在这里插入图片描述

链队列的销毁

在这里插入图片描述

入队

在这里插入图片描述
注意,定义一个新结点时,指向该结点的新指针也随之定义了,例如上面第一行代码中的p,就是新结点的指针

出队

在这里插入图片描述
在这里插入图片描述

取队头元素

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值