数据结构----栈和队列

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

栈和队列时只能插入和删除在表的“端点”的线性表。
其中,栈是后进先出,只在表尾操作LIFO;队列是先进先出(FIFO),只在表尾插入(入栈push),只在表头删除 (出栈pop)。栈顶指向待存入数据的地址。
在这里插入图片描述

1,栈的定义和特点

(1)栈的相关概念:
在这里插入图片描述
(2)栈和一般线性表的区别:仅在于运算规则不同
在这里插入图片描述

2,队列的定义和特点

队列的相关概念:
在这里插入图片描述

3,栈和队列的典型案例

前三个为栈的案例,第四个是队列的案例。
(1)进制转换
用伤做被除数,每次将余数进栈,运行完之后依次出栈就达到了倒序的运算。
在这里插入图片描述

(2)括号匹配的检验
遇到左括号就进栈,遇到右括号就跟当前栈顶匹配,能匹配就将其出栈,否则不匹配。
在这里插入图片描述

(3)表达式求值
在这里插入图片描述
在这里插入图片描述
实际应用后续介绍
(4)舞伴问题
在这里插入图片描述

二、栈的表现和实现

1,栈的抽象数据类型定义

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

2,栈的顺序表示

栈底为表头,栈顶为表尾。另设top和base指针分别指向顺序栈的栈底(低地址段端)和栈顶(为了方便,使top指向栈顶元素之上的下标位置)。stacksize为栈的最大容量。
base= =top是栈空标志。top-base==stacksize是栈满标志。满了之后top就溢出了,称为上溢。所以一般来说top-base都要小于stacksize。
在这里插入图片描述
处理方法2很费时,所以一般不用。
空栈出栈也是溢出,称为下溢。上溢是一种错误,使问题的处理无法进行;而下溢一般认为是约束条件,即问题处理结束。
顺序栈简单方便,但容易溢出(数组大小固定)

3,顺序栈操作

在这里插入图片描述
栈中元素个数:top-base
(1)顺序栈的初始化
在这里插入图片描述
(2)判断是否为空
在这里插入图片描述
top==base,空栈标志。
(3)求顺序栈的长度
在这里插入图片描述
栈中元素个数:top-base
(4)清空顺序栈
无论栈中是否存在元素,直接让top指针指向base指向的空间,就认为空了。
在这里插入图片描述
(5)销毁顺序栈
在这里插入图片描述
直接删除base(将数组回归内存);再让stacksize设置为0,将base和top为空(结构类型中的三个值设置为空),即可释放空间。
(6)顺序栈入栈
在顺序栈非满栈的前提下,将元素入栈之后top+1。指针的*操作为取元素。
在这里插入图片描述

(7)顺序栈出栈
栈非空的前提下,top-1之后再取栈顶元素。
在这里插入图片描述

4,链栈表示和实现

指针方向是灵活变化的,根据需要自行调节。
在这里插入图片描述(1)链栈初始化
在这里插入图片描述
(2)链栈是否为空
在这里插入图片描述
直接判断头指针是否为空

(3)链栈的入栈
对新的结点p分配空间并将新元素赋给data域之后,将头指针存放的头结点的地址放进新结点的next域;再将指针变量p的指赋值给s。
在这里插入图片描述

(4)链栈的出栈
在这里插入图片描述
将头结点的data域的值取出来,用指针p记录取出来的值之后,将头结点的next域赋给s即可。
(5)取栈顶元素
在这里插入图片描述
栈非空的前提下,直接返回头结点的data域。

5,栈和递归

(1)递归的定义:
在这里插入图片描述
(2)常用递归方法的情况

  1. 递归定义的数学函数:斐波拉契数列
  2. 具有递归特性的数据结构:二叉树,广义表
  3. 可递归求解的问题:迷宫问题,hanoi塔

(3)递归问题:分而治之
在这里插入图片描述
在这里插入图片描述
多个函数嵌套调用时,遵循后调用的先返回的原则,用栈实现。递归一定要用到栈。

在这里插入图片描述
(4)递归的优缺点:
在这里插入图片描述
对时间效率要求较高时,可把递归程序改成非递归程序:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里的主调函数也就是Fib(n)
在这里插入图片描述
(5)利用栈改写递归的方法(了解)
在这里插入图片描述
在这里插入图片描述

三、队列的表示和实现

1,队列的类型定义

表尾插入,表头删除的线性表。
在这里插入图片描述

2,队列的顺序表示和实现

(1)队列基本概念
front和rear只是表示位置的下标,不是指针结构。
初始:front=rear=0,空队。
rear=maxsize时,溢出。此时若front不为0,则为假溢出,否则为真溢出。
解决假上溢,用循环队列。
(Q.rear+1)%maxsize的值在0~maxsize-1之间,当队列获取新元素时,(Q.rear+1)%maxsize的值就是下一个rear的地址,要么rear+1,要么是rear回到0的位置,达成循环。
在这里插入图片描述
采用循环队列时,队空队满都是front=rear,怎么判断呢?
在这里插入图片描述
此处使用方法三,则:(Q.rear+1)%maxsizefront时,代表队满。
front=rear代表队空==
(2)队列的初始化:
在这里插入图片描述
在这里插入图片描述
(3)队列的长度
在这里插入图片描述
对于循环队列,(Q.rear-Q.front+maxsize)%maxsize为队列长度,对于普通队列可以直接Q.rear-Q.front
(4)循环队列入队
先判断队列是否为满,非满时可插入到rear指向的地址,再将rear加1。
在这里插入图片描述
(4)循环队列出队
出队只能在表头删除,前提是队列非空。
在这里插入图片描述
(5)取队头元素
队列非空时,直接返回队头指针元素,并且队头指针不变。对于删除(出队)操作,则是取出队头元素并且表头指针+1.

3,队列的链式表示和实现

无法估计所用队列的长度时,采用链队列。
(1)链队列的类型定义:
在这里插入图片描述
(2)链队列的初始化
直接声明一个结点的内存空间,将front和rear指向这块空间,并且front的next域设置为null。
(3)链队列的销毁
从队头结点开始,依次释放所有结点。用一个过渡指针指向待删除结点(front处)的下一个结点,然后释放front,再将p所指地址赋给front;重复上述操作。(直接用现成的尾指针rear代替p,可以少用一个变量)
(4)将元素e入队
先将e放入一个结点空间p的data域,其next为null;然后rear->next=p,再将rear指向p所在节点(Q.rear=p)
(5)链队列出队

在队列非空的前提下,首先为指针变量p赋值,赋的是首元结点的地址,也就是p=Q.front->next;然后将p的data域给元素e,然后修改头结点next域(Q.front->next=p->next),然后删除结点p。
特殊情况,首元结点就是尾结点时,删除该节点之后还要修改尾指针的地址(头尾指针都指向头结点)。
(6)取队头元素
队列非空时,直接返回队头指针元素,并且队头指针不变。e=Q.front->next->data

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值