中缀转后缀表达式

1.遇到操作数:添加到后缀表达式中或直接输出
2.栈空时:遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,输出到后缀表达式,直到弹出的是左括号
注意:左括号不输出到后缀表达式
5.遇到其他运算符:弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈。栈外的想进去,栈内的想出来
6.将栈中剩余内容依次弹出后缀表达式

优先级:

运算符 *,/ +,-
栈内优先级(ISP) 1 5 3 6
栈外优先级(ICP) 6 4 2 1

表达式二叉树先序遍历

编写程序:输入表达式,输出相应二叉树的先序遍历结果
输入: a+b*(c-d)-e/f
输出: -+a*b-cd/ef

解法

  1. 中缀转后缀
  2. 根据后缀式建立二叉树
    • 逐次读取后缀表达式的每一个符号
    • 如果符号是操作数,那么就建立一个单节点树并将一个指向它的指针推入栈中
    • 如果符号是运算符,则从栈中弹出两棵树T1和T2(先弹出T1),并形成一颗以操作符为根的树,其中T1为右儿子,T2为左儿子
    • 将新的树压入栈中,继续上述过程
  3. 先序遍历二叉树
#include
#include
#include
#include
#include
using namespace std;

typedef struct MyStruct
{
     
	char c;
	MyStruct *left;
	MyStruct *right;
	MyStruct():c('0'),left(NULL),right(NULL){
     }
}node;

//中缀转后缀
string z_h(string z) {
     
	map<char, int> ISP{
      {
     '(',1},{
     '*',5},{
     '/',5},{
     '+',3},{
     '-',3},{
     ')',6} };
	map<char, int> ICP{
      {
     '(',6},{
     '*',4},{
     '/',4},{
     '+',2},{
     '-',2},{
     ')',1} };
	string h;
	stack<char> s;
	int i = 0;

	for (i = 0; i < z.size(); i++) {
     
		//遇到操作数
		if (z[i] >= '0'&&z[i] <= '9' || z[i] >= 'a'&&z[i] <= 'z') {
     
			h += z[i];
		}
		else if (z[i] == '(') {
     //遇到左括号
			s.push(z[i]);
		}
		else if (z[i] == ')') {
     //遇到右括号
			while (s.top() != '(') {
     
				h += s.top();
				s.pop();
			}
			s.pop();
		}
		else {
     //遇到其他运算符
			while (!s.empty() && ISP[s.top()] > ICP[z[i]]) {
     
				h += s.top();
				s.pop();
			}
			s.push(z[i]);
		}
	}
	//将栈中剩余内容依次弹出后缀表达式
	while (!s.empty()) {
     
		h += s.top();
		s.pop();
	}

	return h;
}

//先序遍历二叉树
void B(node *t) {
     
	if (t == NULL)
		return;
	cout << t->c;
	B(t->left);
	B(t->right);
}

//根据后缀式建立二叉树
void x(string h)
{
     
	stack<node*> s;
	node *temp = NULL;
	int i = 0;

	for (i = 0; i < h.size(); i++) {
     
		temp = new node;
		temp->c = '0';
		temp->left = temp->right = NULL;

		//如果符号是操作数,那么就建立一个单节点树并将一个指向它的指针推入栈中
		if (h[i] >= '0'&&h[i] <= '9' || h[i] >= 'a'&&h[i] <= 'z') {
     
			temp->c = h[i];
			s.push(temp);
		}
		else {
     
		//如果符号是运算符,则从栈中弹出两棵树T1和T2(先弹出T1),并形成一颗以操作符为根的树,其中T1为右儿子,T2为左儿子
			temp->c = h[i];
			temp->right = s.top();
			s.pop();
			temp->left = s.top();
			s.pop();
			s.push(temp);
		}
	}

	B(s.top());
}


int main() {
     
	string input;
	string str_h;
	string str_x;

	cout << "输入:";
	while (cin >> input) {
     
		str_h = z_h(input);
		cout << "###" << str_h << endl;
		x(str_h);
		cout << "\n输入:";
	}

	return 0;
}

你可能感兴趣的:(中缀转后缀表达式)