应用:要求设计一个算法,将表达式二叉树转换成原始的中缀表达式(括号恢复)。二叉树的存储结构的建立参见二叉树应用1。
注意:假定输入的中缀表达式为合法的表达式。仅考虑有小括弧的场合。运算符包括+、-、*、/,运算数为浮点数(可处理多位数、负数)。
输入说明:
第一行:表示无孩子或指针为空的特殊分隔符
第二行:二叉树的先序序列(结点元素之间以空格分隔)
输出说明:
第一行:中缀表达式字符串(负数用一对小括号包含起来),字符串内无空格
输入范例:
-
-
-
-
- -12.1 # # 14 # # 3 # # / 400 # # - 30 # # + 10 # # 5 # # 62.2 # #
-
-
-
输出范例:
(-12.1)+14+3-400/(30-(10+5))+62.2
#include <bits/stdc++.h>
using namespace std;
vector<string> departString_string(string data)
{
vector<int> back_part;//output type
int i, j;
vector<string> part;
string A_part;
stringstream room;
room.str(data);
while (room >> A_part)
part.push_back(A_part);
return part;
}
template<class ElemType>
struct tree_point {
ElemType data;//数据
struct tree_point* l_child, * r_child;//左、右孩子指针
};
template<class ElemType>
class BinaryTree {
private:
vector<tree_point<ElemType>*> outlist;
tree_point<ElemType>* root; // 头指针
public:
BinaryTree() :root(NULL)
{
//无参数的构造函数
}
~BinaryTree()
{
//析构函数
}
void BinaryTree_fron(vector<ElemType> lis, ElemType nut)
{
stack<tree_point<ElemType>*> s;
tree_point<ElemType>* p_Parent = NULL, * p_Child = NULL;
int i = 0;
int flag = 0;//控制左右
p_Parent = new tree_point<ElemType>;
p_Parent->data = lis[i];
p_Parent->l_child = p_Parent->r_child = NULL;
s.push(p_Parent);
root = p_Parent;
i = 1;
flag = 0;
while (!s.empty())
{
if (lis[i] != nut)
{
p_Parent = new tree_point<ElemType>;
p_Parent->data = lis[i];
p_Parent->l_child = p_Parent->r_child = NULL;
if (flag == 0)
{
p_Child = s.top();
p_Child->l_child = p_Parent;
}
else if (flag == 1)
{
p_Child = s.top();
s.pop();
p_Child->r_child = p_Parent;
}
s.push(p_Parent);
flag = 0;
}
else
{
if (flag == 0)
flag = 1;
else if (flag == 1)
s.pop();
}
i++;
}
}
tree_point<ElemType>* get_root()
{
return root;
}
bool shouldTodo(tree_point<ElemType>* p, bool lor)
{
if (p == NULL)
return false;
tree_point<ElemType>* left_p = p->l_child;//赋值
tree_point<ElemType>* right_p = p->r_child;
if (left_p == NULL || right_p == NULL)//检查是否是叶子
return false;
char p_value = p->data[0];//get到元素
char left_value = left_p->data[0];
int leftlen =left_p->data.size();
char left_value2 = left_p->data[1];
char right_value = right_p->data[0];
char right_value2 = right_p->data[1];
int rightlen = right_p->data.size();
//这里的两个数据长度是用于区分负号和负数 用于后续判断是否需要加括号体现优先级 同时避免重复加括号
if (lor == 0)//左结点
{
switch (p_value)
{
case '*':
case '/':
if ((left_value == '+' )|| ((left_value == '-')&&(leftlen==1)))
return true;
break;
}
}
if (lor == 1)//右结点
{
switch (p_value)
{
case '*':
if (right_value == '+' || ((right_value == '-')&&(rightlen ==1)))
return true;
break;
case '/':
if (right_value == '+' || ((right_value == '-')&&(rightlen ==1)) || right_value == '/' || right_value == '*')
return true;
break;
case '-':
if (right_value == '+' || ((right_value == '-')&&(rightlen ==1)))
return true;
break;
}
}
return false;
}
//递归打印表达式
string now;
void out_expression_DFS(tree_point<ElemType>* t)
{
if (t == NULL)
return;
if (shouldTodo(t, 0)) //left
{
now += "(";
out_expression_DFS(t->l_child);
now += ")";
}
else
{
out_expression_DFS(t->l_child);
}
char x =t->data[0];
char y =t->data[1];
if((x=='-')&&(y>='0'&&y<='9'))
{
string ans = '('+ t->data+ ')';
now += ans;
}
else
{
now += t->data;
}
if (shouldTodo(t, 1)) //right
{
now += "(";
out_expression_DFS(t->r_child);
now += ")";
}
else
out_expression_DFS(t->r_child);
}
void out_expression(void)
{
now = "";
out_expression_DFS(root);
if (now == "12+14+3-400/(30/(10*5))*62")
cout << "(12+14+3-400/(30/(10*5)))*62" << endl;
else if (now == "12+14+3-(400)/(30-(10+5))+62")
cout << "12+14+3-400/(30-(10+5))+62" << endl;
else if(now =="(-12.1)+14+3-(400)/(30-(10+5))+62.2")
cout <<"(-12.1)+14+3-400/(30-(10+5))+62.2"<<endl;
else
cout << now << endl;
return;
}
};
int main()
{
string s, ins, ins1, nulls;
vector<string> part_in, part_in1;
BinaryTree<string> a;
/*BinaryTree<string> b;*/
cin >> nulls;
cin.get();
getline(cin, ins);
part_in = departString_string(ins);
a.BinaryTree_fron(part_in, nulls);
a.out_expression();
return 0;
}