栈的应用——括号匹配;表达式求值;函数递归栈

栈在括号匹配中的应用

#define MaxSize 10
typedef struct{
	char data[MaxSize];
	int top;
}SqStack;
//初始化栈
void InitStack(SqStack &S);
//进栈
bool Push(SqStack &S,char s);
//出栈
bool Pop(SqStack &S,char &s);
//判空
bool EmptyStack(SqStack &s);
//括号换边
char bracketReSide(char bracket){
	if(bracket == ')')return '(';
	if(bracket == ']')return '[';
	if(bracket == '}')return '{';
	return '1';
}
//括号匹配
bool bracketCheck(char str[], int length){
	SqStack I;
	InitStack(&I);
	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 topChar;
			Pop(SqStack,&topChar);
			if(topchar != bracketReSide(str[i]))return false;
		}
	}
	return StackEmpty(I);
}

表达式求值

  • 前缀表达式
  • 中缀表达式
  • 后缀表达式

中缀表达式转后缀表达式

中缀表达式由三部分组成{操作符,运算符,界限符}

手算方法
  1. 确定中缀表达式中各个运算符运算顺序(运算顺序不唯一,因此对应的后缀表达式不唯一)
  2. 选择下一个运算符,按照[左操作数 右操作数 运算符]的方式组成一个新的操作数
  3. 如果还有运算符没被处理,就继续2

解决运算结果不唯一问题:左优先原则——只要左边的运算符能先运算,就优先处理左边的运算

中缀转前缀:右优先原则

后缀表达式求值

手算方法

对于输入的表达式字符串:
从左往右扫描,每遇到一个运算符,就让运算符前面的两个操作数进行运算,并合并成一个操作数

栈在递归当中的应用

函数调用栈

//求n!
int Factorial(int n)
{
	if(n == 0 ||n == 1)return 1;
	return n*Factorial(n-1);
}

//求Fib
int Fib(int n){
	if(n == 0)return 0;
	else if(n == 1)return 1;
	else return Fib(n - 2) + Fib(n - 1);
}	

函数调用的特点:最后被调用的函数最先执行结束(LIFO)
函数调用时,需要用一个“函数调用栈”存储:

  1. 调用返回地址
  2. 实参
  3. 局部变量

递归调用时,函数调用栈可称为“递归工作栈”
每进入一层递归,就将递归调用所需要的信息压入栈顶
每推出一层递归,就从栈顶弹出相应信息

缺点:效率低,太多层递归可能会导致栈溢出,可能包含多次重复运算
可以自定义栈将递归算法改成非递归算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值