数据结构——中缀表达式转化为后缀表达式_栈实现

中缀表达式转化为后缀表达式是实现表达式计算的第一步。这里我给出了中缀表达式中数据为整数类型的转化,没有考虑浮点类型的转化。应用堆栈转化的基本过程:

1、遇到运算符直接输出

2、遇到左括号,压入堆栈

3、遇到右括号,将栈顶元素弹出,直到遇到左括号。不输出括号。

4、若遇到的运算符大于栈顶运算符优先级,则压入堆栈;否则,将栈顶弹出,直到该运算符大于栈顶优先级或者遇到左括号,然后将该运算符压入堆栈。

程序实现:首先要定义数据类型来存储输入的表达式(这个地方对于浮点运算不好处理),然后对于栈定义的数据类型应包括优先级。下面是我写的源代码,代码有点长。欢迎交流,写出更简洁的代码,注意每次测试前先输入回车。

/*
**	中缀表达式转化为后缀表达式
**	数据类型为整型 
*/
#include <stdio.h>
#include <stdlib.h>

typedef struct LNode *List;		/* 存储表达式链表 */	 
struct LNode{
	char c;
	List next;
}; 

typedef struct SNode *Stack; 	/* 存储运算符栈 */ 
struct SNode{
	char opt;		/* 运算符 */		
	int P;			/* 优先级 */ 
	Stack next;
};

List ReadInput();
void Print(List L);
void fun(List L);
Stack Create_Stack();
void  Push(Stack S,char opt);
int Pority_Opt(char opt);
Stack Pop(Stack S);
int ISEmpty(Stack S);

int main()
{
	List L;
	while(getchar() != EOF)
	{
	L = ReadInput();
	Print(L);
	fun(L);
}	
	return 0;
} 

List ReadInput()
{
	List L,P,t;
	char ch;
	L = (List)malloc(sizeof(struct LNode));
	P = L;
	for(; (ch = getchar()) != EOF && ch != '\n';)
	{
		P->c = ch;
		t = P;
		P = (List)malloc(sizeof(struct LNode));
		t->next = P;
	}
	free(P);
	t->next = NULL;
	return L;
}

void Print(List L)
{
	List P=L;
	if(L == NULL)	printf("NULL\n");
	for(; P != NULL; P = P->next)
		printf("%c",P->c);
	printf("\n");
}

/*
**	中缀表达式转后缀表达式
**	栈实现,只适用于整数表达式 
*/ 
void fun(List L)
{
	List P;
	Stack S;
	int Pt;
	S = Create_Stack();
	for(P = L; P != NULL; P = P->next) 
	{
		if(P->c >= '0' && P->c <= '9')
			printf("%c",P->c);	
		else{
			printf(" ");
			if( ISEmpty(S) )		/* 第一次运算符压栈 */ 
				Push(S,P->c);
				
			else{
				if(Pority_Opt(P->c) > S->next->P && P->c != ')')	/* 运算符优先级大于栈顶运算符优先级 */
					Push(S,P->c);		/* 压栈 */
					
				else if(Pority_Opt(P->c) <= S->next->P){			/* 运算符优先级小于等于栈顶运算符优先级 */
					while( !ISEmpty(S) && Pority_Opt(P->c) <= S->next->P && (S->next->opt - '(' != 0) )		/* 弹栈,一直到大于栈顶优先级 */
					{																	/* 或者遇到'(' */ 
						Stack St = Pop(S);		
						printf("%c ",St->opt);							
					}
					Push(S,P->c);
				} 
				
				else{						/* 遇到 ')' */ 
					Stack St = Pop(S);			
					while( !ISEmpty(S) && (St->opt - '(' != 0) )		/* 弹栈,一直到 '('*/
					{
						if(St->opt != '(')	printf("%c ",St->opt);																	
						St = Pop(S);										
					}	
				} 
				
			}		
		}
		if( P->next == NULL && !ISEmpty(S) ){
			Stack St = Pop(S);
			printf(" %c ",St->opt);	
		} 
	}
} 

/*
**	创建带有头结点的空栈
*/ 
Stack Create_Stack()
{
	Stack S = (Stack)malloc(sizeof(struct SNode));
	S->next = NULL;
	return S;
} 

/*
**	压栈
*/
void  Push(Stack S,char opt)
{
	Stack T = (Stack)malloc(sizeof(struct SNode));	
	T->opt = opt;
	T->P = Pority_Opt(opt);		/* 计算优先级 */
	T->next = S->next;
	S->next = T; 
}

/*
**	计算运算符优先级
*/ 
int Pority_Opt(char opt)
{
	switch(opt){
		case '(': return 3;
		case ')': return 3;
		case '*': return 2;
		case '/': return 2;
		case '+': return 1;
		case '-': return 1;
		default: return 0;		/* 错误 */ 
	}
}

Stack Pop(Stack S)
{
	Stack t=S->next;
	
	if(ISEmpty(S)){
		printf("空栈\n");
		return NULL;
	}
	else{
		S->next = t->next;
		return t;
	}
}

int ISEmpty(Stack S)
{
	return S->next == NULL;
} 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值