堆栈
堆栈的应用场合
- 逆序输出:处理与输出次序的过程颠倒;递归深度与输出长度不易预知
- 递归嵌套
- 延迟缓存
- 栈式计算
逆序输出
进制转换
十进制转换为其他进制的过程,计算是从上至下,输出是从下往上
括号匹配:遇到‘(’就进栈,遇到‘ ) ’就出栈
扩展:多种括号匹配({},(),[]),无论是什么类的左括号,只要遇到左括号就入栈,遇到右括号就出栈。出栈时只有遇到相同类型的左括号才能是匹配成功,反之就是匹配失败。例如:[ ( ] )就是匹配失败的情况。HTML中的标签就是利用了括号匹配
延迟缓存
中缀求值: 处理多位数的方法:如果读到数字就放入操作数栈中,转向下一位,如果还是数字字符,就把操作数栈顶的数取出来*10,再加上这个数
后缀求值: 遇到操作数就入栈,遇到运算符就去栈中取出相应需要的操作数的个数,进行相应的计算,再把得到的结果放回栈中
栈混洗
一个序列根据一个栈中转而得到其他的序列
栈混洗总数(catalan数):(2n)! / (n!)*(n+1)!
表达式求值
/*
中缀表达式转换后缀表达式
思路:
栈内<栈外:入栈操作符
栈内>=栈外:出栈操作符
遇到 ‘(’:直接入栈
遇到 ‘)’:出栈所有操作符直达遇到 ‘(’
计算后缀表达式的值
思路
从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,
遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。
补:
中缀直接求值
中缀表达式还有前缀表达并求值
用二叉树转换中缀表达式到中缀表达式和中缀表达式
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# define Max 1000
typedef struct Node* NodeP;
typedef struct Node
{
int Data[Max];
int Top;
}Node;
NodeP S=NULL;
NodeP Head=NULL;
NodeP Creat()
{
NodeP P=NULL;
P=(NodeP)malloc(sizeof(Node));
P->Top=-1;
return P;
}
void Push(NodeP S,int ch)
{
if(S->Top==Max-1)
{
printf("满\n");
return;
}
S->Data[++S->Top]=ch;
return;
}
int Top(NodeP S)
{
int ch=0;
if(S->Top==-1)
return -1;
ch=S->Data[S->Top];
return ch;
}
int Pop(NodeP S)
{
int ch=0;
if(S->Top==-1)
{
printf("空\n");
return 0;
}
ch=S->Data[S->Top--];
return ch;
}
int Level(char ch)
{
int m=0;
switch(ch)
{
case '(': m=0;break;
case ')': m=0;break;
case '+': m=1;break;
case '-': m=1;break;
case '*': m=2;break;
case '/': m=2;break;
}
return m;
}
void SuffixeExp(char* Head) //中缀表达式转换后缀表达式函数
{
int i=0;
char ch;
char* P=Head;
char A[1000]={'\0'};
while(*P!='\0')
{
if(*P>=48 && *P<=57)
{
A[i++]=*P;
if(*(P+1)<48 || *(P+1)>57)
A[i++]=' '; //加空格是为了区分每个数
}
else
{
while(1)
{
ch=Top(S); //堆栈空返回零 不然就返回操作符号
if(ch>=0)
{
if(*P=='(') //遇到 ‘(’:直接入栈
{
Push(S,(int)*P);
break;
}
if(Level(*P)>Level(ch)) //栈内<栈外:入栈操作符
{
Push(S,(int)*P);
break;
}
else //栈内>=栈外:出栈操作符
{
if(ch!='(')
{
A[i++]=ch;
A[i++]=' ';
Pop(S);
}
else //出栈所有操作符直达遇到 ‘(’
{
Pop(S);
break;
}
}
}
else //堆栈为空直接入栈
{
Push(S,(int)*P);
break;
}
}
}
P++;
}
ch=Top(S);
while(ch>=0) //把栈内剩下的操作符全部输出
{
A[i++]=ch;
A[i++]=' ';
Pop(S);
ch=Top(S);
}
A[i-1]='\0';
strcpy(Head,A);
return;
}
void Evaluation(char* P)
{
int sum=0;
int top1=0,top2=0;
while(*P!='\0')
{
if(*P>=48 && *P<=57) //数字与数字还有表达式都是用空格隔开,所以循环求字符串表达的整数
sum=sum*10+*P-'0';
else if(*P==32) //如果为空格,并且前面为数字不是操作符号,那么入栈
{
if(*(P-1)>=48 && *(P-1)<=57)
{
Push(Head,sum);
sum=0;
}
}
else
{
top1=Pop(Head); //如果是操作符,取栈顶两个元素进行计算
top2=Pop(Head);
int total=0;
if(*P=='+')
total=top2+top1;
else if(*P=='-')
total=top2-top1;
else if (*P=='*')
total=top2*top1;
else
{
if (top1!=0) //只要程序中有/号出现,一定要检测除数为零的情况
{
total=top2/top1;
}
else
{
printf("表达式错误,出现除数为零的情况出现\n");
return;
}
}
Push(Head,total);
}
P++;
}
sum=Pop(Head);
printf("%d\n",sum);
return;
}
int main()
{
S=Creat();
Head=Creat();
char A[1000];
scanf("%s",A);
SuffixeExp(A);
Evaluation(A);
return 0;
}

浙公网安备 33010602011771号