Chapter 4 Stacks and Queues
第 4 章 栈与队列
栈(stack)
限定仅在表尾进行插入和删除操作的线性表
允许插入和删除元素的一端称为栈顶(top)[表头],另一端称为栈底(bottom)[表尾],不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表(Last In First Out),简称LIFO结构
类似网页中的后退操作,最后看的网站会最先被弹出
栈的插入:进栈(压栈(栈顶不动)[需要进行移位 O(n) 复杂度]、入栈(栈底不动)[不需要移位 O(1) 复杂度])
栈的删除:出栈(弹栈)
进栈出栈的变化形式
保证栈顶元素先出栈,而不一定严格遵循先进后出。
栈的抽象数据类型
理论上线性表的操作特性他都具备,但其插入和删除操作会有变化。(进栈和出栈操作)
栈的顺序存储结构及实现
栈的顺序存储(顺序栈)
设置栈底(bottom/base)、栈顶(top)变量
数组下标为 0 的一端作为栈底;
栈顶 top(指针变量)的位置必须小于 StackSize,当栈存在一个元素时,top = 0;
空栈时 top = -1;
栈中元素个数 = top - base;
进栈、出栈操作
顺序栈的基本操作:进栈操作
void
Push(ElementType X,Stack S)
{
if(IsFull(S))
Error("Full stack");
else
S->Array[++S->TopOfStack] = X;
}
顺序栈的基本操作:出栈操作
两者不涉及循环语句,时间复杂度为 O(1) ;
链栈:栈的链式存储结构
两栈共享空间
两个栈共用一个数组,栈底为数组的两端,增加元素时,栈顶向中间靠拢,当top1+1=top2时,两个栈顶碰头,栈满
这样的数据结构适用于两个栈的空间需求有相反关系时,一个栈增长而另一个栈在缩短时;
例如:买卖股票时,你买入,就一定会有一个人卖出;
有人赚钱,就有人赔钱;
并且这个操作也只适合两个具有相同数据类型的栈;
栈的链式存储结构及实现
简称链栈;
链栈不需要头结点,链栈的栈顶在单链表的头部;
对于链栈来说,基本不存在栈满情况,除非内存已经没有可以使用的空间;
对于空栈,链表原定义是头指针指向空,那么链栈的空就是top=NULL;
链栈的进栈、出栈操作
与单链表的链式存储结构基本相似,但有不同
链栈的进栈和出栈操作都很简单,没有任何的循环操作,时间复杂度为O(1)
对比顺序栈和链栈
时间复杂度均为O(1);
空间性能上:顺序栈需要事先确定一个固定长度;链栈则要求每个元素都有指针域,但对栈的长度无限制
总结:如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,不能最好用链栈,反之,如果它的变化在可控范围内,建议用顺序栈会更好一些。
栈的应用——递归
例:斐波那契数列
当前项等于前两项之和
f(n)=f(n-1)+f(n-2)
递归中栈的思想:在调用递归函数时:对于每一层递归,函数的局部变量、参数值、以及返回地址都被压入栈中。在返回阶段,位于栈顶的局部变量、参数值和返回地址被弹出,用于返回调用层次中执行代码的剩余部分,也就恢复了调用的状态
栈的应用——四则运算表达式求值
含有括号的运算表达
遇到左括号就进栈,遇到右括号就出栈,然后对期间进栈的数做运算。
后缀表达式,数字先进栈,遇到运算符就出栈,做运算。
而我们平时写的标准四则运算表达式称为中缀表达式
所以计算机需要将中缀表达式转化为后缀表达式,再利用栈进行运算
栈的应用——迷宫问题
队列(queue)
定义:只允许在一端进行插入操作,而在另一端进行删除操作的线性表
队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。
同样是线性表,队列也有类似线性表的各种操作,不同的就是插入数据只能在队尾进行,删除数据只能在队头进行
假定:front指针变量指向队头元素,rear指针指向队尾元素的下一个位置
循环队列
普通顺序存储队列,类似线性表的顺序存储结构,先进先出,然后所有位置前移
若不前移,则会发生假溢出(数组的前面有空位,而后面无法再插入元素)
于是循环队列:解决假溢出。
循环队列:队列的头尾相接的顺序存储结构
队列满的条件是:(rear+1)%QueueSize==front
通用的计算队列长度的公式:(rear-front+QueueSize)%QueueSize
队列的链式存储结构及实现
其实就是线性表的单链表,只不过它只能尾进头出而已,我们把他简称为链队列。
循环队列与链队列
时间上:基本都是常数时间O(1)
但对于链队列,需要频繁申请和释放结点,会有一定的时间消耗
空间上:循环队列必须有一个固定长度,链队列更为灵活
循环队列可能存在溢出或者空间浪费问题
总的来说:在可以确定队列长度最大值的情况下,建议使用循环队列,如果无法预估队列的长度,则使用链队列
Last updated