数据结构与算法##3.栈与队列
一、栈
LIFO 限制访问端口的线性表
push pop top
应用:表达式求值,消除递归,深度优先搜索,子程序/函数调用的管理
案例:火车进出栈问题
1.实现方式
-
顺序栈
顺序表的简化版,关键是确定哪一端作为栈顶
有上溢和下溢问题(元素超出最大数目或小于0) -
链式栈
用单链表实现,指针方向自顶而下
时间效率上两者所有的操作都是常数时间,难分伯仲
空间效率上顺序栈须说明一个固定的长度,链式栈的长度可变,但增加结构性的开销。
实际应用中顺序栈比链式栈用得更广泛
2.表达式求值
- 中缀表达式
运算符在中间
需要括号改变优先级
数字-》常数-》因子-》项-》表达式 - 后缀表达式
运算符在后面
完全不需要括号
循环:依次顺序读入表达式的符号序列
当遇到操作数时,压入栈顶
当遇到运算符时,从栈中两次去除栈顶,按照运算符对这两个操作数进行计算,然后将结果压入栈顶
直到遇到=,取出栈顶的值即为结果
3.递归
- 递归出口:最小子问题的求解(可以有多个出口)
- 递归规则:将原问题划分成子问题,保证递归的规模向出口条件靠拢(递归体+界函数)
非递归实现:
- 建立迭代
- 递归转换为非递归
Hanoi塔问题
通过内部栈和子程序交换信息
递归运行时,堆栈的进退以及通过堆栈传递参数
函数运行时的动态存储分配
- 栈:用于分配后进先出的数据
- 堆:用于不符合后进先出的(指针指向地址)
函数调用及返回步骤:
-
调用
保存调用信息
分配数据区
控制转移给被调函数的入口 -
返回
保存返回信息
释放数据区
控制转移到上级函数(主调用函数)
4.递归转非递归
- 机械方法
1.设置一工作栈当前工作记录
2.设置t+2个语句标号
3.增加非递归入口
4.替换第i个递归规则
5.所有递归出口处增加语句:goto label t+1
6.标号为t+1的语句格式
7.改写循环和嵌套中的递归
8.优化处理
二、队列
FIFO 两端操作
front , rear
enqueue dequeue getfront isempty isfull
1.实现方式
- 顺序队列:关键是如何防止假溢出
使用数组存储数据,指向队头队尾的下标在数组内循环
固定的存储空间 - 链式队列
单链表队列,链接方向从队尾指向队头
可以满足大小无法估计的情况
2.应用
- 调度或缓冲
- 宽度优先搜索