栈
先进后出,LIFO(last in first out),只能在表尾做插入删除操作的线性表
栈顶:允许插入和删除的一端
栈底:最先进栈
空栈:没有数据元素
压栈、入栈:插入操作
弹栈、出栈:删除操作
只限制插入删除的位置,不限制进出的时间
1、2、3依次进栈
出栈次序
- 1,2,3进,3,2,1出,321
- 1进1出,2进2出,3进3出,123
- 1、2进,2、1出,3进3出,213
- 1进,1出、2、3进,3、2出,132
- 1、2进,2出,3进3出,1出,231
抽象数据类型
Stack
Data:相同类型,相邻元素有前驱和后继
Operation:
InitStack(*S) : 初始化操作,建立一个空栈S。
DestroyStack(*S) : 若栈存在,则销毁它。
ClearStack(*S) : 将栈清空。
StackEmpty(S) : 若栈为空,返回true,否则返回false。
GetTop(S, * e) : 若栈存在且非空,用e返回S的栈顶元素
Push(*S, e) : 若栈S存在,插入新元素e到栈S中并成为栈顶元素
Pop(*S, *e) : 删除栈S中栈顶元素,并用e返回其值。
StackLength(S) : 返回栈S的元素个数。
顺序栈
0做栈底,top做栈顶
top <= StackSize-1
空栈 top<0
存取定位方便
出入栈
出栈,判空,获取要删除的元素,top–
入栈,判满,top++,插入新元素
时间复杂度O(1)
两栈共享空间
一个数组,存两个栈
栈底在数组两端,0、n-1
向中间靠拢,top1、top2
栈空:top1=-1,top2=n
栈满:top1+1=top2
两个相同数据类型栈的空间需求有相反关系
链栈
链栈:栈的链式结构
栈顶放在头部,头指针做栈顶指针
不需要头结点
不会栈满、在内存中找任意空闲位置,长度无限制,不会空间浪费
空栈:top=NULL
每个元素都有指针域,增加内存开销
出入栈
时间复杂度O(1)
应用
递归
递归函数:直接或间接调用自己的函数
至少有一个条件满足时递归不再进行,不再引用自身而是返回值退出
迭代:循环结构
递归:选择结构
优点:方便理解
缺点:递归会建立函数副本,耗费大量时间和内存
前行阶段(存储数据):每一层递归的函数局部变量,参数值,返回地址压入栈中
退回阶段(恢复数据):弹出位于栈顶的局部变量,参数值,返回地址,返回调用该层,执行代码的其余部分
前行和退回逆序
斐波那契数列
相邻两项之和,构成后一项
n=0;F(n)=0
n=1;F(n)=1
n>1;F(n)=F(n-1)+F(n-1)
四则运算表达式
中缀转后缀
后缀出结果
中缀转后缀
中缀表达式 9+(3-1)*3+10/2
从左到右遍历中缀表达式
数字输出
符号,判断其与栈顶元素的优先级,
右括号依次出栈,去掉左括号并输出
优先级低则依次出栈并输出,把当前符号进栈
后缀(逆波兰)
后缀表达法:不需要括号,所有的符号在运算数字的后面出现
后缀表达式 9 3 1 - 3 * + 10 2 / +
从左往右遍历后缀表达式的每个数字和符号
数字进栈
遇到符号,栈顶两个数字出栈,计算结果进栈
队列
先进先出,FIFO(First In First Out),一端插入,另一端删除的线性表
队尾:允许插入的一端
队头:允许删除的一端
排队
抽象数据类型
Queue
Data:相同类型,相邻元素有前驱和后继
Operation:
InitQueue(*Q) : 初始化操作,建立一个空队列Q。
DestroyQueue(*Q) : 若队列Q存在,则销毁它。
ClearQueue(*Q) : 将队列Q清空。
QueueEmpty(Q) : 若队列Q为空,返回true,否则返回false。
GetHead(Q, * e) : 若队列Q存在且非空,用e返回队列Q的队头元素。
EnQueue(*Q, e) : 若队列Q存在,插入新元素e到队列Q中并成为队尾元素。
DeQueue(*Q, * e) : 删除队列Q中队头元素,并用e返回其值。
QueueLength(Q) : 返回队列Q的元素个数
顺序队列
1、队头在下标为0位置
入队(插入)操作:在队尾追加,不需要移动,时间复杂度O(1)
出队(删除)操作:队列所有元素都向前移动,保证队头(下标为0)元素不为空,时间复杂度O(n)
2、队头不固定
front指向队头
rear指向队尾元素的下一个位置
空队列:front=rear
假溢出:rear已经到数组末尾,但数组还有空闲位置
循环队列
头尾相连的顺序结构的队列
由于空队列和满队列都是rear==front
所以定义为:当数组中只剩一个空闲元素时,队列满
判满:(rear+1)%QueueSize==front
队列长度:(rear-front+QueueSize)%QueueSize
时间复杂度O(1)
提前占用空间,数组溢出\空间浪费
链队列
链队列:尾进头出的线性单链表
队头指向头结点,负责删除
队尾指向终端结点,负责插入
空队列:front和rear都指向头结点
时间复杂度O(1),申请释放结点->时间开销
指针域->空间开销,但不需要提前固定长度,用多少占多少不会浪费空间