栈和队列的应用
栈和队列的应用
栈的括号匹配问题
-
依次扫描所有字符,遇到坐括号入栈,遇到右括号则弹出栈顶元素检查是否匹配
-
匹配失败的情况:1.左括号单身2.右括号单身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) //栈顶元素出栈,用x返回 bool Pop(SqStack &S,char &x) 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);//检索完所有括号之后,栈空说明匹配成功 }
考试中也要声明接口,即那些函数的中午注释
虽然我们声明的都是静态数组,容量大小无法改变,但是考试中写更简单,也是可以的
后缀表达式的计算
-
用栈实现后缀表达式(手算):
-
从左到右扫描下一个元素,直到处理完所有元素
-
若扫描到操作数则入栈,并返回到1;否则执行3
-
若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结果压回栈顶,回到1
注意:先出栈的是”右操作数“
-
-
中缀表达式转后缀表达式(机算)
初始化一个栈,用于保存暂时还不能确定运算顺序的运算符。
从左到右处理各个元素,直到末尾,可能出现三种情况:
- 遇到操作数。直接加入后缀表达式
- 遇到界限符。遇到
(
直接入栈;遇到)
则依次弹出栈内运算符并加入后缀表达式,直到弹出(
为止。注意:(
不加入后缀表达式 - 遇到运算符。依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到
(
或栈空则停止。之后再吧当前运算符入栈
按上述方法处理完所有字符后,将栈中剩余运算符依次弹出,并加入后缀表达式
前缀表达式的计算
-
用栈实现前缀表达式:
-
从右到左扫描下一个元素,直到处理完所有元素
-
若扫描到操作数则入栈,并返回到1;否则执行3
-
若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结果压回栈顶,回到1
注意:先出栈的是”左操作数“
-
中缀表达式的计算(用栈实现)
- 初始化两个栈,操作数栈和运算符栈
- 若扫描到操作数,压入操作数栈
- 若扫描到运算符或界限符,则按照“中缀转后缀”相同的逻辑压入运算符栈(期间也会弹出运算符,每弹出一个运算符时,就需要在弹出两个操作数栈的栈顶元素并执行相应的运算,运算结果再压回操作数栈)