mirror of
https://github.com/Didnelpsun/CS408.git
synced 2026-02-11 14:45:57 +08:00
45 lines
2.4 KiB
Markdown
45 lines
2.4 KiB
Markdown
# 栈
|
||
|
||
栈结构与线性表类似,是只允许一端(表尾)进入或删除的线性表。即后进先出LIFO。
|
||
|
||
栈顶就是允许插入和删除的一端,而另一端就是栈底。
|
||
|
||
进栈顺序:A->B->C->D,出栈顺序:D->C->B->A。
|
||
|
||
如果有$n$个不同的元素进栈,出栈元素不同排列的个数为$\dfrac{1}{n+1}C_{2n}^n$,这就是卡特兰数。
|
||
|
||
## 顺序栈
|
||
|
||
### 顺序栈定义
|
||
|
||
### 顺序栈操作
|
||
|
||
#### 顺序栈初始化
|
||
|
||
栈顶指针初始化为-1,因为索引最小为0。如果初始化为0也可以,不过其操作有所不同。
|
||
|
||
## 链栈
|
||
|
||
链栈基本上就是只能操作一头的链表,所以从定义上其基本上没有区别。
|
||
|
||
## 栈的应用
|
||
|
||
1. 数制转换:
|
||
+ 思想:先求出来的余数放在后边。
|
||
+ 如43(10) = 101011(2)。
|
||
2. 括号匹配:
|
||
+ 思想:自左至右扫描表达式,若遇左括号,则将左括号入栈,若遇右括号,则将其与栈顶的左括号进行匹配,若配对,则栈顶的左括号出栈,否则出现括号不匹配错误。
|
||
3. 表达式求值(中缀表达式求值):
|
||
+ 思想:优先级最低。
|
||
+ 例如:4+2×3-10/5,按照运算法则,我们应当先算2×3然后算10/5 ,再算加法,最后算减法。
|
||
+ 我们设定两个栈,一个用于存储运算符称之为运算符栈,另一个用于存储操作数称之为操作数栈。
|
||
1. 首先置操作数栈为空,表达式起始符“#”为运算符栈的栈低元素。
|
||
2. 依次读入表达式中每个字符,若是操作数则进操作数栈,若是运算符则和运算符栈栈顶元素比较优先级,若栈顶元素优先级高于即将入栈的元素,则栈顶元素出栈(优先级高的先出栈,再把优先级低的放进来),操作数栈pop出两个操作数和运算符一起进行运算,将运算后的结果放入操作数栈,直至整个表达式求值完毕(即运算符栈顶元素和要放入元素均为“#”)
|
||
4. 迷宫问题:
|
||
+ 思想:以栈S记录当前路径,则栈顶中存放的是“当前路径上最后一个位置信息”。
|
||
+ 若当前位置“可通”,则纳入路径(入栈),继续前进。
|
||
+ 若当前位置“不可通”,则后退(出栈),换方向继续探索。
|
||
+ 若四周“均无通路”,则将当前位置从路径中删除出去。
|
||
5. 递归调用
|
||
6. 程序运行时的函数调用。
|