只允许在一端进行插入或删除操作的线性表。(后进先出)
选择题:
队列的大题;出对入队的
基本操作
initStack(&S):初始化栈。
DestroyStack:销毁栈。
Push(&S,x):进栈。将x加入成为新的栈顶。
Pop(&S,&x):出栈。弹出栈顶元素,并用x返回。
GetTop(S,&x):读栈顶元素。
n个不同元素进栈,Cn,2n/n+1
顺序栈
定义
#define MaxSize 10 typedef struct{ ElemType data[MaxSize]; int top; }SqStack; //初始化栈 void InitStack(SqStack &S){ S.top=-1; } //判断栈空 bool StackEmpty(SqStack S){ if(S.top==-1){ return true; }else{ return false; } } //入栈 bool Push(SqStack &S,ElemType x){ if(S.top==MaxSize-1){ return false; } S.data[++S.top]=x;//先移动指针后添加数据 return true; } //出栈 bool Pop(SqStack &S,ElemType &x){ if(S.top==-1){ return false; } x=S.data[S.top--]; return true; }
链栈(不带头结点)
定义以及基本操作
#define MAXSIZE 100 typedef int SElemType; typedef int Status; //链栈的存储结构 typedef struct StackNode { SElemType data; struct StackNode* next; }StackNode, * LinkStack; //链栈的初始化 Status InitStack(LinkStack& S) { //构造一个空栈S,栈顶指针置空 S = NULL; return OK; } //链栈的入栈 Status Push(LinkStack& S, SElemType e) { //在栈顶插入元素e,链栈不需要判断栈满 StackNode* p = new StackNode; p->data = e; p->next = S; S = p; return OK; } //链栈的出栈 Status Pop(LinkStack& S, SElemType& e) { //删除S的栈顶元素,用e返回其值 if (S == NULL) //判断是否为栈空 return ERROR; e = S->data; StackNode* p = S; S = S->next; delete p; return OK; } //取链栈的栈顶元素 SElemType GetTop(LinkStack S, SElemType &e) { //返回S的栈顶元素,不修改栈顶指针 if (S != NULL) //非栈空时返回 return S->data; return ERROR; } //遍历输出链栈 Status StackTraverse(LinkStack S) { StackNode* p = S; if (p == NULL) { cout << "链栈为空!" << endl; return ERROR; } cout << "栈顶->"; while (p != NULL) { cout << p->data << " "; p = p->next; } cout << endl; return OK; }
应用
1.括号匹配问题
#define MaxSize 10 typedef struct{ ElemType data[MaxSize]; int top; }SqStack; void InitStack(SqStack &S){ S.top=-1; } bool StackEmpty(SqStack S){ if(S.top==-1){ return true; }else{ return false; } } bool Push(SqStack &S,ElemType x){ if(S.top==MaxSize-1){ return false; } S.data[++S.top]=x; return true; } bool Pop(SqStack &S,ElemType &x){ if(S.top==-1){ return false; } x=S.data[S.top--]; return true; } bool bracketCheck(char str[],int length){ SqStack S; InitStack(S); for(int i=0;i<length;i++){ if(str[i]=='('||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; if(str[i]=='}'&&topElem!='{') return false; } } return StackEmpty(S); }
2.表达式求值
三种算术表达式:中缀表达式;后缀表达式,前缀表达式
后缀表达式相关:中缀表达式转后缀表达式;后缀表达式求值(左优先原则)先弹出的元素是“右操作数”
前缀表达式相关:中缀表达式转前缀表达式,前缀表达式求值(右优先原则)先弹出的元素是“左操作数”
中缀转后缀的表达式(机算)
3.递归
递归-》非递归可以使用栈,循环。
4.共享栈
优点:节省空间,降低上溢可能。