1 栈的定义
栈是只允许一端进行插入或删除的线性表
1.1 栈的基本操作:
- InitStack(&S):初始化栈。构造一个空栈S,分配内存空间
- DestroyStack(&L):销毁栈。销毁并释放栈S所占用的内存空间
- Push(&S,x):进栈,若栈S未满,则将新进栈的元素作为新栈顶
- Pop(&S,&x):出栈,若栈S非空,则弹出栈顶元素,并用x返回
- GetTop(S,&x):读栈顶元素,若栈S非空,则用x返回栈顶元素
- StackEmpty(S):判断一个栈S是否为空。若S为空,则返回true,否则返回true
2 顺序栈
2.1 顺序栈的定义实现
#define MaxSize 10
typdef struct {
ElemType data[MaxSize];// 存放栈中元素
int top;// 栈顶指针
}SqStack;
2.2 初始化操作
void InitStack(SqStack &S){
s.top = -1;// 初始化栈顶指针
}
2.3 进栈操作
bool Push(SqStack &S,ElemType x) {
if(S.top == MaxSize-1)// 栈满
return false;
S.data[++top] = x;// 指针先向上移动一位,再赋值
return true;
}
2.4 出栈操作
bool Pop(SqStack &S,ElemType &x) {
if(S.top == -1)// 栈空
return false;
x = S.data[top--];// 先把值保存给x,再将指针向下移动
return true;
}
2.5 共享栈
两个栈共享一片空间的叫做共享栈。
- 定义
#define MaxSize 10
typedef struct {
ElemType data[MaxSize];
int top0;// 0号栈
int top1;// 1号栈
}ShStack;
- 初始化
void InitStack(ShStack &S) {
s.top0 = -1;// 初始化栈顶指针
s.top1 = MaxSize;
}
- 栈满条件:s.top0+1 == s.top1
3 链栈:操作跟链表差不太多,只不过被限制在头结点后处操作
3.1 定义
用链式存储实现的栈
typedef struct LinkNode{
ElemType data;
struct LinkNode *next;
}*LiStack
3.2 初始化操作
bool InitLiStack(LiStack &L) {
L = (LinkNode*)malloc(sizeof(LinkNode));
if(L == Null){
return false;
}
L->next = Null;
return L:
}
3.3 出栈操作:仅仅在头结点后处操作
bool LiStackDelete(LiStack &L,ElmeType &e) {
if(L->next == Null) {
return false;
}
LNode *q = L->next;
e = q->data;
q->next = L->next;
free(q);
return q;
}
3.4 进栈操作:仅仅在头结点后处操作
bool LiStackInsert(LiStack &L,ElmeType e) {
LNode *q = (LNode *)malloc(sizeof(LNode));
if(q == Null) {
return false;
}
q->data = e;
q->next = L->next;
L->next = q;
return true;
}
3.5 读取栈顶元素操作
bool GetTop(LiStack S,&x) {
if(S->next == Null) {
return false;
}
x = S->next->data;
return true;
}
3.6 栈空,不考虑栈满
bool StackEmpty(LiStack S){
if(S->next == Null) return true;
else return false;
}
4 栈的应用
4.1 括号匹配
4.1.1 问题描述
假设表达式中允许包含两种括号:()、[],其嵌套的顺序任意即([])、[()]均可。[()、((())均为不正确格式。简单来说就是要匹配上“(”要匹配上“)”、“[“要匹配上”]”。
4.1.2 算法描述
- 初始设置一个空栈,顺序读入括号
- 若是右括号,则使将栈顶元素登出得以匹配,或者不匹配,则退出程序
- 若是左括号则入栈。算法结束时,栈为空,否则括号匹配失败
4.1.3 代码实现
// 定义
#define MaxSize 10
typedef struct {
char data[MaxSize];
int top;
}SqStack;
// 初始化
void InitStack(SqStack &S);
// 判空
bool StackEmpty(SqStack S);
// 入栈
bool Push(SqStack &S,char x);
// 出栈
bool Pop(SqStack &S,char &x);
// 匹配
bool bracketCheck(char str[],int length) {
SqStack S;
InitStack(S);
for(int i = 0; i <lenght; i++) {// 顺序扫描
if(str[i] == '('|| str[i] == '[' ) {
Push(S,str[i]);
}else{
if(StackEmpty(S)) return false;
char topElem;
Pop(S,topElem);
if(str[i] == ')' && topElem!='(')
return false;
if(str[i] == ']' && topElem!='[')
return false;
}
}
}
4.2 表达式求值
4.2.1 概念
算式表达式由操作数、运算符、界限符组成。
4.2.2 中缀转后缀
转换思路:
例子:
转换思路(机算):
后缀表达式的计算方法(手算):
后缀表达式的计算方法(机算):
4.2.3 中缀转前缀
转换思路:
前缀表达式的计算方法(机算):