栈应用之中缀转后缀表达式(C语言版)

==> 学习汇总(持续更新)
==> 从零搭建后端基础设施系列(一)-- 背景介绍


数学定义请自行百度,这里仅用大白话讲一下转换规则。

完整代码下载

中缀转后缀表达式转换规则:
文字说明:

1、如果是数字(包括小数点)则直接存放到数组suffix中(或者输出)

2、如果是左括号,则直接入栈 3、如果是右扩号,则出栈,直到遇到‘(’为止,并把‘(’出栈 4、如果是+-,若栈中无元素或者栈顶有‘(’,则直接入栈,否则全部出栈(遇到'('也停止)后再入栈(因为+-运算符优先级最低) 5、如果是*/,若栈顶优先级低于当前运算符,则直接入栈,否则先出栈再入栈 6、最后把栈中的运算符都出栈 图解示例:

栈应用之中缀转后缀表达式(C语言版)_第1张图片

1、
栈应用之中缀转后缀表达式(C语言版)_第2张图片

2、
栈应用之中缀转后缀表达式(C语言版)_第3张图片

3、
栈应用之中缀转后缀表达式(C语言版)_第4张图片

4、
栈应用之中缀转后缀表达式(C语言版)_第5张图片

5、
栈应用之中缀转后缀表达式(C语言版)_第6张图片

中缀转后缀表达式代码(部分):

//判断是否是数字
bool IsDigit(char ch)
{
	return (ch >= '0' && ch <= '9') || ch == '.' ? true : false;
}

//判断是否是操作符
bool IsOperator(char ch)
{
	return ch == '+' || ch == '-' || ch == '*' || ch == '/'? true : false;
}

//判断运算符的优先级,-1表示小于,0表示等于,1表示大于
int GetPriority(char op1 , char op2)
{
	if ((op1 == '+' || op1 == '-') && (op2 == '-' || op2 == '+'))
		return 0;
	else if (op1 == op2)
		return 0;
	else if ((op1 == '+' || op1 == '-') && (op2 == '*' || op2 == '/'))
		return 1;
	else if ((op1 == '*' || op1 == '/') && (op2 == '-' || op2 == '+'))
		return -1;
	else if ((op1 == '*' || op1 == '/') && (op2 == '*' || op2 == '/') && op1 != op2)
		return 0;
}

//根据运算符计算两数
double Calc(double op1, double op2, char op)
{
	switch (op)
	{
	case '+': return op2 + op1;
	case '-': return op2 - op1;
	case '*': return op2 * op1;
	case '/': if (op1 != 0) return op2 / op1;
			  else return 0;
	default:  return 0;
	}
}

//中缀转后缀表达式
void InfixToSuffix(const char* infix, char* suffix)
{
	LPLINKSTACK stack = CreateStack();   //创建一个栈
	int iLen = strlen(infix);            //计算长度用来控制循环
	double num = 0;
	int k = 0;
	for (int i = 0;i < iLen;i++)
	{
		//1.略过空格
		if(infix[i] == ' ')
			continue;
		//2.如果是数字(包括小数)直接输出
		else if (IsDigit(infix[i]))   
			suffix[k++] = infix[i];
		//3.如果是左括号,则直接入栈
		else if (infix[i] == '(')
			PushC(stack, infix[i]);
		//4.如果是右扩号,则出栈,直到遇到‘(’为止,并把‘(’出栈
		else if (infix[i] == ')')
		{
			while (GetTopC(stack) != '(')	
				suffix[k++] = PopC(stack);
			Pop(stack);
		}
		//5.如果是+-,若栈中无元素或者栈顶有‘(’,则直接入栈,否则全部出栈(遇到'('也停止)后再入栈(因为+-运算符优先级最低)
		else if (infix[i] == '+' || infix[i] == '-')
		{
			//加一个分隔符,区分2位以上的数字
			suffix[k++] = ' ';
			if (IsEmpty(stack) || GetTopC(stack) == '(')
				PushC(stack, infix[i]);
			else
			{
				do
				{
					suffix[k++] = PopC(stack);
				} while (!IsEmpty(stack) && GetTopC(stack) != '(');
				PushC(stack, infix[i]);
			}
		}
		//6.如果是*/,若栈顶优先级低于当前运算符,则直接入栈,否则先出栈再入栈
		else if (infix[i] == '*' || infix[i] == '/')
		{
			//加一个分隔符,区分2位以上的数字
			suffix[k++] = ' ';
			//当前运算符的优先级大于栈顶的优先级的时候直接入栈
			if (GetPriority(GetTopC(stack), infix[i]) == 1)
				PushC(stack, infix[i]);
			else
			{   //当栈不为空,且当前运算符的优先级小于等于栈顶的优先级,栈顶不是‘(’,才能出栈
				while (!IsEmpty(stack) && (GetPriority(GetTopC(stack), infix[i]) < 1) && GetTopC(stack) != '(')
					suffix[k++] = PopC(stack);
				PushC(stack, infix[i]);
			}
		}
	}
	//7.最后把栈中的运算符都出栈
	while (!IsEmpty(stack))
		suffix[k++] = PopC(stack);
}









约瑟夫问题详解+源码
线性表之循环队列

线性表之链队列

线性表之顺序队列

线性表之链栈

线性表之顺序栈

线性表之双向链表

线性表之循环链表

线性表之单链表

线性表之顺序表

你可能感兴趣的:(数据结构)