注意:
对于a+(b-c)可拆括号变成a+b-c,同样对于a*(b/c)可拆括号变成a*b/c;// + 与 *
而对于a-(b+c)不可拆括号变成a-b+c,同样对于a/(b*c)不可拆括号变成a/b*c。// - 与 /
问题描述
内容:(1)请参照链表的ADT模板,设计二叉树并逐步完善的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的链表ADT原型文件,自行设计二叉树的ADT。)
注意:二叉树ADT的基本操作的算法设计很多要用到递归的程序设计方法。
(2)ADT的简单应用:使用该ADT设计并实现若干应用二叉树的算法设计。
应用:要求设计一个算法,将表达式二叉树转换成原始的中缀表达式(括号恢复)。二叉树的存储结构的建立参见二叉树应用1。
注意:假定输入的中缀表达式为合法的表达式。仅考虑有小括弧的场合。运算符包括+、-、*、/,运算数为浮点数(可处理多位数、负数)。
参考函数原型:
(1)表达式二叉树转换成中缀式 (外壳部分,用户函数)
//表达式二叉树转换成中缀式
template<class ElemType>
void BianryTree_Infix(BinaryTree<ElemType> &T, string &inffix); //inffix:转换获得的中缀表达式字符串
(2)表达式二叉树转换成中缀式 (递归部分,用户函数)
//表达式二叉树转换中缀表达式
template<class ElemType>
void BianryTree_Infix_Cursive(BinaryTreeNode<ElemType> *root, string &inffix);
辅助函数:
(1)判断是否为运算符(用户函数)
//判断是否为运算符
bool isoperator( string op ){
if( op == "+" || op == "-" || op == "*" || op == "/" || op == "(" || op == ")" )
return true;
return false;
}
(2)求运算符的优先级(用户函数)
//求运算符的优先级
int getOperPri(char op)
{
switch(op)
{
case '(':
return 1; break;
case '+':
case '-':
return 2; break;
case '*':
case '/':
return 3; break;
default:
return 0;
}
}
输入说明
第一行:表示无孩子或指针为空的特殊分隔符
第二行:二叉树的先序序列(结点元素之间以空格分隔)
输出说明
第一行:中缀表达式字符串(负数用一对小括号包含起来),字符串内无空格
输入范例
#
+ - + + -12.1 # # 14 # # 3 # # / 400 # # - 30 # # + 10 # # 5 # # 62.2 # #
输出范例
(-12.1)+14+3-400/(30-(10+5))+62.2
AC代码:
#include<iostream>
#include <sstream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<vector>
#include <climits>
#define MAX_SIZE 100
using namespace std;
bool sign;
//结点
template<class ElemType>
struct BinaryTreeNode
{
ElemType data;
BinaryTreeNode<ElemType> *LChild, *RChild;
BinaryTreeNode() : LChild(NULL), RChild(NULL){}
BinaryTreeNode(const ElemType &item, BinaryTreeNode<ElemType> *Lptr = NULL, BinaryTreeNode<ElemType> *Rptr = NULL)
{
LChild = Lptr;
RChild = Rptr;
data = item;
}
};
//二叉树
template<class ElemType>
class BinaryTree
{
private:
BinaryTreeNode<ElemType> *root;
public:
BinaryTree():root(NULL){}
BinaryTree(const ElemType &item){root = new BinaryTreeNode<ElemType>(item);}
void makeBinaryTree( const ElemType &item, BinaryTree &left, BinaryTree &right);
//返回二叉树结点的个数int BinaryTreeSize( BinaryTreeNode<ElemType> *T ) const;
//判断二叉树是否为空
bool BinaryTreeisEmpty() const{return root == NULL;}
//获取根结点元素值
ElemType GetRootData() const{ return root->data;}
void SetRoot(BinaryTreeNode<ElemType> * p){ root = p;}
BinaryTreeNode<ElemType> * GetRoot() const{ return root;}
bool PreOrderTraverse( BinaryTreeNode<ElemType> *T ); //前序遍历(递归)//num的初始值为0,作用为控制输出格式(最后1个结点后不加“,”)
bool InOrderTraverse( BinaryTreeNode<ElemType> *T ); //中序遍历(递归)
bool PostOrderTraverse( BinaryTreeNode<ElemType> *T ); //后序遍历(递归)
BinaryTreeNode<ElemType>* CreateBinaryTree(vector<ElemType> &x, ElemType &empty, int &n);
};
template<class ElemType>
BinaryTreeNode<ElemType>* BinaryTree<ElemType>::CreateBinaryTree(vector<ElemType> &x, ElemType &empty, int &n)
{
ElemType ch = x[n];//string
n++;
if (ch == empty)
{
return NULL;
}
else
{
BinaryTreeNode<ElemType> *Node = new BinaryTreeNode<ElemType>;
Node->data = ch;
Node->LChild = CreateBinaryTree(x, empty, n);
Node->RChild = CreateBinaryTree(x, empty, n);
return Node;
}
}
//辅助函数
bool isoperator( string op )
{
if( op == "+" || op == "-" || op == "*" || op == "/" || op == "(" || op == ")" )
return true;
return false;
}
int getOperPri(string op)
{if(op=="(")
return 1;
else if(op=="+"||op=="-")
return 2;
else if(op=="*"||op=="/")
return 3;
else return 0;}
//开始操作
template<class ElemType>
void BianryTree_Infix_Cursive(BinaryTreeNode<ElemType> *root, vector<ElemType> &inffix)
{
if(root)
{
string t=" ",l=" ",r=" ";
if(root->LChild&&root->RChild)
{
t=root->data;l=root->LChild->data;
r=root->RChild->data;
}
if(isoperator(l)&&getOperPri(l)<getOperPri(t))
{
inffix.push_back("(");
BianryTree_Infix_Cursive(root->LChild,inffix);
inffix.push_back(")");
}
else
{
BianryTree_Infix_Cursive(root->LChild,inffix);
}
inffix.push_back(root->data);
if(t=="+")
{BianryTree_Infix_Cursive(root->RChild,inffix);
}
else if((t == "-" && isoperator(r)) &&(getOperPri(t) >= getOperPri(r)))
{inffix.push_back("(");
BianryTree_Infix_Cursive(root->RChild,inffix);
inffix.push_back(")");
}
else if(t == "/" && isoperator(r))
{
inffix.push_back("(");
BianryTree_Infix_Cursive(root->RChild,inffix);
inffix.push_back(")");
}
else if((t=="*"&&isoperator(r))&&getOperPri(t)>getOperPri(r))
{
inffix.push_back("(");
BianryTree_Infix_Cursive(root->RChild,inffix);
inffix.push_back(")");
}
else
{
BianryTree_Infix_Cursive(root->RChild,inffix);
}
}}
template<class ElemType>
void BianryTree_Infix(BinaryTree<ElemType> &T, vector<ElemType> &inffix)
{
BianryTree_Infix_Cursive(T.GetRoot(),inffix);
}
template<class ElemType>
void CreateTree(BinaryTree<ElemType> &T, ElemType &str, ElemType &empty)
{
ElemType tmp;
vector<ElemType> t;
stringstream input_T(str);
while(input_T >> tmp)
{
t.push_back(tmp);
}
BinaryTreeNode<ElemType> *root;
int num = 0;
root = T.CreateBinaryTree(t, empty, num);
T.SetRoot(root);
}
int main()
{
BinaryTree<string> T;
string str;
string empty;
getline(cin,empty);
getline(cin,str);
CreateTree(T,str,empty);
vector<string> inffix;
BianryTree_Infix(T,inffix);
for(auto i : inffix)
{
if(i[0]=='-'&&i.size()>1)cout<<'('<<i<<')';
else cout<<i;
}
return 0;
}