您的位置:首页 > 理论基础 > 数据结构算法

数据结构-----栈(逆波兰表达式)----中缀转后缀

2014-04-02 22:05 323 查看


一、中缀表达式转换为逆波兰式

       将一个普通的中序表达式转换为逆波兰表达式的一般算法是:

1、首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。

2、读入一个中缀表达式,为了方便起见,可在其最右端追加一个最低优先级运算符(如:#号)。(这样做的目的是,最后读入#号运算符时将运算符栈中所有运算符都输出)。

3、从左至右扫描该中缀表达式,如果当前字符是数字,则分析到该数字串的结束,并将该数字串直接输出。

4、如果不是数字,该字符则是运算符,此时需比较该运算符与运算符栈顶运算符的优先关系:

(1)、若该运算符优先级高于栈顶运算符优先级别(或栈为空),则直接将该运算符压入运算符栈中;

(2)、若该运算符优先级小于或等于此运算符栈顶的运算符,则弹出栈顶运算符并输出,重复比较、输出,直到栈为空或该运算符优先级高于栈顶运算符,然后将该运算符入栈。

5、重复上述操作(3)-(4)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,输出结果便是中缀表达式转化为逆波兰表示的简单算术表达式。

二、代码实现

#include <stdio.h>
#include <stdlib.h>

#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10

typedef char ElemType;
typedef struct//栈
{
ElemType *base;
ElemType *top;
int stackSize;
}sqStack;

void InitStack(sqStack *s)//创建一个以数组进行存储的栈
{
s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
if( !s->base )
exit(0);

s->top = s->base;
s->stackSize = STACK_INIT_SIZE;
}

void Push(sqStack *s, ElemType e)//压栈
{
// 栈满,追加空间
if( s->top - s->base >= s->stackSize )
{
s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
if( !s->base )
exit(0);

s->top = s->base + s->stackSize;
s->stackSize = s->stackSize + STACKINCREMENT;
}

*(s->top) = e; // 存放数据
s->top++;
}

void Pop(sqStack *s, ElemType *e)//出栈,将数据存储于e
{
if( s->top == s->base )
return;

*e = *--(s->top); // 将栈顶元素弹出并修改栈顶指针
}

int StackLen(sqStack s)//返回栈中有效元素的长度
{
return (s.top - s.base);
}

int main()
{
sqStack s;
char c, e;

InitStack( &s );

printf("请输入中缀表达式,以#作为结束标志:");
scanf("%c", &c);

while( c != '#' )
{
while( c>='0' && c<='9' )//输出这个数字串
{
printf("%c", c);
scanf("%c", &c);
if( c<'0' || c>'9' )
{
printf(" ");
}
}

if( ')' == c )//遇到')',一直出栈,直到'('出栈
{
Pop(&s, &e);
while( '(' != e )
{
printf("%c ", e);
Pop(&s, &e);
}
}
else if( '+'==c || '-'==c )
{
if( !StackLen(s) )//如果栈为空,则直接压栈
{
Push(&s, c);

}
else
{
do
{
Pop(&s, &e);//退出栈顶元素,若是'(',直接将'+'或'-'压入栈中(得现将'('压栈)
if( '(' == e )
{
Push(&s, e);//将'('压栈
}
else//若是'+','-','*','/',则向屏幕输出此栈顶元素
{
printf("%c ", e);
}
}while( StackLen(s) && '('!=e );
Push(&s, c);//将'+'或'-'压栈
}
}
else if( '*'==c || '/'==c || '('==c )//遇到'*'、'/'、'(',直接压栈
{
Push(&s, c);
}
else if( '#'== c )
{
break;
}
else
{
printf("\n出错:输入格式错误!\n");
return -1;
}

scanf("%c", &c);
}

while( StackLen(s) )//将栈中的剩余操作符全部输出
{
Pop(&s, &e);
printf("%c ", e);
}

return 0;
}

三、效果展示

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息