回顾一下逆波兰式:
逆波兰表达式又叫做后缀表达式。逆波兰表示法是波兰逻辑学家J・卢卡西维兹于1929年首先提出的一种表达式的表示方法。后来,人们就把用这种表示法写出的表达式称作“逆波兰表达式”。逆波兰表达式把运算量写在前面,把算符写在后面。
重点:
- 符号栈中,栈顶优先级最高
- 向符号栈中加入符号时,要对比栈顶符号的优先级是否小于当前符号的优先级,如果小于则直接入栈,如果大于则要将栈内元素弹出,一直弹出至当前的栈顶符号的优先级小于当前符号,然后再将当前符号入栈
- 如果入栈符号为 ( ,则直接入栈
- 如果入栈符号为 ) ,则要循环弹栈,一直到栈顶元素为 ( ,为止,最后还要将栈顶元素 ( 弹出
优先级:
±优先级小于 * /,且 + 和 - 的优先级相同, * 和 / 的优先级相同
原文链接:https://blog.csdn.net/assiduous_me/article/details/101981332
如果当前元素是数字,那么就直接压入栈
如果当前元素是运算符,那么一次性弹出两个元素,同时后弹出来的作为加数或者被减数或者乘数或者被除数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 100
typedef enum{character,operate}flag;
//括号字母,操作符加减乘除
typedef struct Node
{
char elem;//字符
int rank;//优先级
flag tag;//标志
}Node;
typedef struct BiNode
{
Node data;//元素
struct BiNode *left,*right;
}BiNode,*BiTree;
typedef struct NewString
{
Node data[max];
int length;//长度
}NewString;
//初始化字符串
NewString InitString()
{
char str[max];
NewString S;
int len=0,level=0;//长度,基本优先级
scanf("%s",str);
len = strlen(str);
S.length=len;
for(int i=0;i<S.length;i++)
{
S.data[i].elem=str[i];//赋值
//分辨等级
if(str[i]=='+'||str[i]=='-')
{
S.data[i].rank=level+1;
S.data[i].tag=operate;
//加减优先级+1
}
else if(str[i]=='*'||str[i]=='/')
{
S.data[i].rank=level+2;
S.data[i].tag=operate;
//乘除优先级+2
}
else if(str[i]=='(')
{
S.data[i].rank=level+2;
level += 2;
}
else if(str[i]==')')
{
S.data[i].rank=level-2;
level -= 2;
}
else
{
//字母不计优先级
S.data[i].tag=character;
}
}
return S;
}
//去掉括号
void ClearBrackets(NewString* S)
{
int level=0;
if(S->data[0].elem=='('&&S->data[S->length-1].elem==')')
{
for(int i=0;i<S->length-2;i++)
{
if(S->data[0].elem=='(')
{
level++;
}
else if(S->data[0].elem==')')
{
level--;
}
if(level==0)
{
return;
}
}
for(int i=0;i<S->length-2;i++)
{
S->data[i]=S->data[i+1];//向前挪一位,把第一位(与最后一位)去掉
}
S->length=S->length-2;//长度-2
}
}
//找到最低优先级位置
int FindMin(NewString *S)
{
int pos=0,min=1000;
for(int i=0;i<S->length;i++)
{
if(S->data[i].tag==operate && S->data[i].rank<=min)
{
min=S->data[i].rank;
pos=i;
}
}
return pos;
}
//创建二叉树
BiTree CreateBiTree(NewString *S)
{
BiTree T;
T=(BiTree)malloc(sizeof(BiNode));
NewString *left,*right;
left=(NewString*)malloc(sizeof(NewString));
right=(NewString*)malloc(sizeof(NewString));
int midpos,len;
len=S->length;
if(len==1)
{
T->data=S->data[0];
T->left=NULL;
T->right=NULL;
}
else
{
midpos=FindMin(S);
left->length=midpos;
for(int i=0;i<left->length;i++)
{
left->data[i]=S->data[i];
}
right->length=S->length-midpos-1;
for(int i=0;i<right->length;i++)
{
right->data[i]=S->data[midpos+i+1];
}
ClearBrackets(left);//清理一下括号
ClearBrackets(right);
T->data=S->data[midpos];
T->left=CreateBiTree(left);
T->right=CreateBiTree(right);
}
return T;
}
//后序遍历
void LRDPrint(BiTree T)
{
if(T==NULL)
{
return;
}
else
{
LRDPrint(T->left);
LRDPrint(T->right);
printf("%c",T->data.elem);
}
}
int main()
{
NewString S;
S=InitString();
BiTree T;
T=CreateBiTree(&S);
LRDPrint(T);
return 0;
}