# 栈 栈结构与线性表类似,是只允许一端(表尾)进入或删除的线性表。即后进先出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. 程序运行时的函数调用。