C语言实现中缀表达式到后缀表达式的转换

中缀表达式到后缀表达式的转换是堆栈应用的典型例子。通过只允许操作‘+’,‘-’,‘*’,‘/’,并坚持优先级法则,即可实现该操作。

1. 规则

假设读入的中缀表达式是正确的。
当读到操作数时,立即输出。
操作符不立即输出,而是放入栈中。定义‘(’的优先级最高,其余符号同四则运算的法则。读入一个操作符时,弹出栈顶元素直至发现优先级更低的元素为止。除非是在处理一个‘)’,否则绝不从栈中弹出‘(’。遇到‘)’,将栈顶元素弹出并输出直到遇到相应的‘(’,但该‘(’只弹出,不输出。
读入输入的末尾时,若栈非空,依此弹出并输出所有栈元素。

2. 实例

以中缀表达式1+(2 -3 )*4+5 / 6 为例:
首先读入1,并输出。接着读入‘+’,此时栈为空,将‘+’压入栈中
C语言实现中缀表达式到后缀表达式的转换_第1张图片
这时读入‘(’,由于栈顶元素‘+’比‘(’的优先级低,故没有输出,‘(’进栈。接着,2被读入并输出。

C语言实现中缀表达式到后缀表达式的转换_第2张图片
接着‘-’读入,除非在处理‘)’,否则‘(’不会从栈中弹出。因此将‘-’压入栈中。下一个是3,被读入并输出。
C语言实现中缀表达式到后缀表达式的转换_第3张图片
此时读入‘)’,因此将栈元素直到‘(’弹出,输出一个‘-’。
C语言实现中缀表达式到后缀表达式的转换_第4张图片
接着读入‘’,栈顶元素‘+’优先级较低,故将乘号压入栈中。同时4被读入并输出。
C语言实现中缀表达式到后缀表达式的转换_第5张图片
继续进行,‘+’被读入,此时需要把‘
’从栈弹出并输出;现在栈顶元素为‘+’,该算符不比刚刚遇到的‘+’优先级低而是具有相同的优先级,因而被弹出并放入输出中。然后,将谷歌遇到的‘+’压入栈中。同时5被读入并输出。
C语言实现中缀表达式到后缀表达式的转换_第6张图片
现在,读入‘/’,该算符优先级高于栈顶元素,因而被压入栈中。再往后读入6,并将其输出。
C语言实现中缀表达式到后缀表达式的转换_第7张图片
至此,输入为空,因而将栈元素全部弹出并输出,直至栈为空。
C语言实现中缀表达式到后缀表达式的转换_第8张图片

3. 代码

#include
#include
#include

#define EmptyTOS -1        //栈空时指针指向
#define MinStackSize 5     //栈的最小容量
#define MaxArraySize  50   //待读取数组初始最大容量

typedef struct StackRecord* Stack;

struct StackRecord
{
	int capacity;          //栈容量
	int TopOfStack;        //栈顶
	char* array;
};

Stack CreateStack(int size)        //创建空栈
{
	Stack s;
	if (size < MinStackSize)
	{
		printf("The size is too small!\n");
		return;
	}
	s = (Stack)malloc(sizeof(struct StackRecord));
	s->capacity = size;
	s->TopOfStack = EmptyTOS;
	s->array = (char*)malloc(sizeof(char) * size);
	
	return s;
}

int IsEmpty(Stack s)
{
	return s->TopOfStack == EmptyTOS;
}

int IsFull(Stack s)
{
	return s->TopOfStack == s->capacity - 1;
}

void Push(Stack s, char c)        //压栈
{
	if (IsFull(s))
	{
		printf("Error: the Stack is full!");
		return;
	}
	else
	{
		s->array[++(s->TopOfStack)] = c;
	}
}

char Top(Stack s)      //返回栈顶元素,不弹出
{
	if (IsEmpty(s))
	{
		printf("Error: the Stack is empty!");
		return;
	}
	else
		return s->array[s->TopOfStack];
}

char Pop(Stack s)        //弹出栈顶元素
{
	if (IsEmpty(s))
	{
		printf("Error: the Stack is empty!");
		return;
	}
	else
		return s->array[s->TopOfStack--];
}

int IsHigherThan(char x, char y)       //优先级定义,'('具有最高优先级,其余同四则运算
{
	if ((x == '(') && ((y == '+') || (y == '-') || (y == '*') || (y == '/')))
		return 1;
	else if (((x == '*') || (x == '/')) && ((y == '+') || (y == '-')))
		return 1;
	else
		return 0;
}

void InfixToPostfix(char* a)       //中缀转后缀
{
	Stack s = CreateStack(50);
	int i = 0;

	while (a[i]!='\0')
	{
		if ((a[i] >= '0' && a[i] <= '9') || (a[i] >= 'a' && a[i] <= 'z') || (a[i] >= 'A' && a[i] <= 'Z')) 
			printf("%c ", a[i]);      //数字直接输出
		else if (a[i] == ')')        
		{
			while (Top(s) != '(')
				printf("%c ", Pop(s));       //遇到右括号,弹出并输出栈顶元素直到遇到左括号(左括号不输出)
			Pop(s);
		}
		else
		{
			if (IsEmpty(s))   //栈空则直接推入栈中
				Push(s, a[i]);
			else if (IsHigherThan(a[i], Top(s)))     //优先级高则推入栈中
				Push(s, a[i]);
			else
			{
				while (!IsEmpty(s) && (!IsHigherThan(a[i], Top(s))))   //弹出栈顶元素直至遇到优先级更低的元素
				{
					if (Top(s) != '(')    //只有遇到右括号才能将左括号弹出
						printf("%c ", Pop(s));
					else
						break;
				}
				Push(s, a[i]);
			}
		}
		i++;
	}

	while (!IsEmpty(s))    //输入读取完毕栈非空,则依此弹出所有栈元素
	{
		printf("%c ", Pop(s));
	}
}

int main()
{
	char str[MaxArraySize];
	printf("Enter the infix:\n");
	gets(str);
	printf("The postfix:\n");
	InfixToPostfix(str);

	return 0;
}

4.测试

在这里插入图片描述
在这里插入图片描述

你可能感兴趣的:(数据结构与算法,堆栈,数据结构,算法,c语言)