链式堆栈---实现中缀表达式转后缀表达式


在堆栈中将中缀表达式转换成后缀表达式的算法为:


实现程序如下:

/*-------------------------------------------- 
目的:堆栈应用学习
功能:中缀表达式转后缀表达式
作者:刘志强
完成时间:2015-1-6 耗时10小时 

太笨了 :::>_<::: 
---------------------------------------------*/ 
#include <stdio.h> 
#include <stdlib.h>
#include <string.h>

#define ElementType char

/*------------------------------------------*/ 
/*定义堆栈链表数据结构*/ 
typedef struct Node {
	ElementType Data;
	struct Node *Next;
}LinkStack;
//LinkStack *Top;
LinkStack *Input;

/*------------------------------------------*/ 
/*------------------------------------------*/ 
void main()
{	
	ElementType input[100];
	Input=CreateStack ();
	printf("请输入中缀四则运算表达式(英文半角下输入):\n"); 
	gets(input);
	printf("转换后的逆波兰表达式为;\n"); 
	calculate(input);
	printf("\n\n");	
	system("pause>nul"); 
} 


/*------------------------------------------ 
转换函数;将中缀表达式转换成后缀表达式
------------------------------------------*/  
void calculate(ElementType input[])
{
	int i=0;
	ElementType TopElem,PreTopElem,PrecedeResult;
	LinkStack *FirstItem;
	for(i=0;input[i]!='\0';i++)
	{
		if (input[i]>='0'&&input[i]<='9'||input[i]=='.'||input[i]>='a'&&input[i]<='z')  //输出数字部分 
			printf("%c",input[i]);
		else if(input[i]=='(')  //将左括号压栈 
		{
			Push (input[i] ,Input);
		}	
		else if(input[i]==')')	//遇到右括号,将栈内元素弹出打印直到遇到左括号 (左括号不打印) 
		{
			/*do
			{	
				TopElem = Pop (Input);
				printf(" #%c#",TopElem);	
			}while((TopElem!='(')&&(!IsEmpty(Input))) ;
			*/
			TopElem = Pop (Input);
			while((TopElem!='(')&&(!IsEmpty(Input)))  //一定要防止进入死循环 
			{				
				printf(" %c",TopElem);	
				TopElem = Pop (Input);
				//printf(" #%c#",TopElem);
			}
			
			//PreTopElem=TopElem;	
			//printf("%c",PreTopElem);	
		}
		else if(input[i]=='+'||input[i]=='-'||input[i]=='*'||input[i]=='/')
		{
			printf(" ");
			if (IsEmpty (Input)) //栈空则进栈 
			{
				Push (input[i] ,Input);
				
			}	
			else 
			{	
				FirstItem=Input->Next;
				if(FirstItem->Data!='(')  //栈顶元素非左括号 
				{
					PrecedeResult=Precede(FirstItem->Data,input[i]); //和栈顶元素比较
					//printf("%c%c",PreTopElem,PrecedeResult); 
					if(/*PreTopElem=='('&&*/PrecedeResult=='=') //结合性处理部分 
					{
						TopElem = Pop (Input);
						printf("%c ",TopElem);
						Push (input[i] ,Input);
					}
					else if(PrecedeResult=='>')  //元素优先级大于栈顶元素优先级则进栈 
					{
						Push (input[i] ,Input);
					} 
					else //小于等于则输出Top元素,直到大于则进栈 
					{
						while(!IsEmpty (Input))
						{
							TopElem = Pop (Input);
							printf("%c ",TopElem);
							
							if(!IsEmpty (Input))
							{
								FirstItem=Input->Next;
								PrecedeResult=Precede(FirstItem->Data,input[i]);
								//printf("%c",PrecedeResult);
							}	
							
							if(IsEmpty (Input))
							{
								Push (input[i] ,Input);
								break;   // !!!为空进栈则陷入死循环 !!! 
							}
							else if(PrecedeResult=='>')
							{
								//printf(":::>_<:::");
								Push (input[i] ,Input);
								break;	
							}
							
						}
					}					
				}
				else if(FirstItem->Data=='(') //栈顶元素是左括号则元素进栈 
					Push (input[i] ,Input);										
			}
		}
	}
	while(!IsEmpty (Input))
	{
		TopElem = Pop (Input);
		printf(" %c",TopElem);
	}
}

/*------------------------------------------*/ 
//判断优先级函数 
/*------------------------------------------*/ 
char Precede(char dest,char input)
{
	 //判断两个运算符s1,s2的优先顺序,
	 char back;
	 switch(input)
	 {
	  case '+': 
	  case '-': if(dest=='*'||dest=='/')
	     			back='<';
	     		else if(dest=='+'||dest=='-')   /*!!!注意考虑结合性 !!! */
	     			back='<' ;
				else
	      			back='>';
	     		break;
	  case '*': 
	  case '/': if(dest=='+'||dest=='-')
	      			back='>';
	      		else if(dest=='*'||dest=='/')   /*!!!注意考虑结合性 !!! */
	      			back='=';
	     		else 
	      			back='<';
	     		break;
	  default : printf(" ERROR ");
	            break;
	 }
	 return back;
}

/*------------------------------------------*/ 
/*创建堆栈*/
/*------------------------------------------*/ 
LinkStack *CreateStack ()
{
	LinkStack *S;
	S=malloc(sizeof(struct Node));
	S->Next=NULL;
	return S; 
}

/*------------------------------------------*/ 
/*判断堆栈是否为空*/
/*------------------------------------------*/ 
int IsEmpty (LinkStack *S)
{
	return S->Next==NULL;
	printf("NULL");
}

/*------------------------------------------*/ 
/*将数据压入堆栈*/
/*------------------------------------------*/ 
void Push (ElementType item ,LinkStack *S)
{
	struct Node *TmpCell;
	TmpCell=malloc(sizeof(struct Node));
	TmpCell->Data=item;
	TmpCell->Next=S->Next;
	S->Next=TmpCell; 
}

/*------------------------------------------*/ 
/*从堆栈弹出数据*/
/*------------------------------------------*/ 
ElementType Pop (LinkStack *S)
{
	struct Node *FirstCell;
	ElementType TopElem;
	if(IsEmpty(S))
	{
		printf("Stack is Empty!");
		return NULL;
	}
	else
	{
		FirstCell=S->Next;
		S->Next=FirstCell->Next;
		TopElem=FirstCell->Data;
		free(FirstCell);
		return TopElem;
	}
} 

好好学习,多学多用 大笑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值