[TOC]
一、顺序栈
- 存储结构:顺序存储
- 后进后出,插入和删除只在栈顶进行
- 递归
- 附设指针top指示栈顶元素在顺序栈的位置
1.定义
1 | #define MAXSIZE 100 //存储空间的初始分配量 |
①看栈空
S.top = -1; //指针指向元素
S.top = NULL;
S.top = 0; //指针指向栈顶元素的下一个位置
s.top = S.base;
②看栈长
length = S.top - S.base; //指针指向栈顶元素的下一个位置
③看栈满
top - base = stacksize; //指针指向栈顶元素的下一个位置
2.初始化
- 分配存储空间,new int[]
- 如果分配失败,!base,返回-1
- 否则使空栈,栈顶=栈底
- 使定义中的stacksize获得最大容量
1 | int InitStack(SqStack &S){ |
3.入栈
- 判断栈满
- 否则对e取值
- 移动指针
1 | int Push(SqStack &S,int e){ |
4.出栈
- 判断栈空
- 否则栈顶-1
- 出栈元素赋给元素e
1 | int Pop(SqStack &S,int &e){ |
5.取栈顶元素
- 判断栈非空
- 返回当前栈顶元素的值,不修改指针
1 | int GetTop(SqStack S){ |
二、链栈
1.定义
1 | typedef struct StackNode { |
链栈是操作受限的单链表,只能在链表的头部进行操作,故没有必要附加头结点。
- 栈顶指针就是链表的头结点。
- 链栈插入与删除仅在栈顶处执行(头插法/头删法)。
- 栈无栈满问题,空间可扩充适合于多栈操作。
2.初始化
1 | int InitStack(LinkStack &S){ |
3.入栈
- 为入栈元素e分配空间,用指针p指向 p= new LinkStack
- 对新结点赋值e
- 把新结点插入到栈顶
- 修改栈顶指针为p
1 | int Push(LinkStack &S,int e){ |
4.出栈
- 判断栈空
- 否则将栈顶元素赋值给e
- 用结点p临时保存栈顶元素的空间
- 下移栈顶指针
- 释放p结点
1 | int Pop(LinkStack &S,int &e){ |
5.读栈顶元素
- 当栈非空,返回S的值,栈顶S保持不变
1 | int GetTop(LinkStack S){ |
三、用堆栈求解后缀表达式
1.定义
后缀表达式是一种不需要括号的表达式,其本身是对栈的一种应用。
与之对应的是中缀表达式,即我们现在使用的四则运算。
2.运算规则
顺序:从左到右入栈。
对于数字直接入栈,对于运算符号,就把栈最上面的两个数出栈,进行运算后再重新入栈。式子最后的结果出栈。
栈顶元素永远在运算符的右边。
3.例子
1 | (1)令P代表入栈,O代表出栈。当利用堆栈求解后缀表达式1 2 3 + * 4 –时,堆栈操作序列是: |
1、2、3:进栈,PPP
+:对最顶上的3、2出栈,计算2+3=5,把结果进栈,OOP
*:对5、1出栈,计算5x1=5,把结果进栈,OOP
4:进栈,P
-:对4、5出栈,计算4-5=-1,把结果进栈,OOP
最后输出结果:O
答案为D。
1 | (2)表达式`a*(b+c)-d`的后缀表达式是: |
数字优先进栈,所以abc
括号内的式子优先计算,所以首先遇到+,为abc+
算完加法算乘法,所以abc+*
继续将d进栈,然后算减法,所以是abc+*d-
答案为A。