表达式树(二叉树)的实现
一、 该程序的功能,实现了前缀表达式转换为中缀表达式,并进行相应的求值和赋值运算,与及构造复合表达式的功能。
二、实现原理,利用二叉树实现,也可以称为语法树,树中维护了中缀表达式。
三、 概要设计:
实现该程序所要用到的函数如下(从左到右为相关函数调用层次),除main函数外,其他函数均是两个类的成员函数,这两个类分别是:TreeNode类和BinaryTreeAndExpr类:
四、 详细设计(这里直接给出源码,由于比较容易,就不做过多说明):
1、Expression.h文件的实现
#ifndef _EXPRESSION_H_
#define _EXPRESSION_H_
//-------------------- 树节点类
class TreeNode
{
public:
TreeNode(char_data,TreeNode* _left,TreeNode* _right);
~TreeNode();
charGetData();
voidSetData(char _data);
voidSetLeft(TreeNode* _left);
voidSetRight(TreeNode* _right);
TreeNode*GetLeft();
TreeNode*GetRight();
private:
charData;
TreeNode*left,*right;
};
//-------------------- 二叉树几及表达式类
class BinaryTreeAndExpr
{
public:
BinaryTreeAndExpr();
~BinaryTreeAndExpr();
TreeNode*GetRoot();
voidSetRoot(TreeNode* _root);
voidReadExpr(char* E);
voidWriteExpr(char* E);
voidAssign(char v,int c);
staticint Value(char* E);
staticBinaryTreeAndExpr* CompoundExpr(char p,char* E1,char* E2);
voidRelease();
private:
voidReleaseRecursion(TreeNode* &p);
voidReadExprRecursion(TreeNode* &p,char* E);
voidWriteExprRecursion(TreeNode* p,char* E);
voidAssignRecursion(TreeNode* p,char v,int c);
intValueRecursion(TreeNode* p);
intPriority(char c1,char c2);
boolIsOperator(char c);
intEvaluation(int a,char op,int b);
TreeNode*root;
intExpr_i,Expr_len;
};
#endif
2、Expression.cpp文件的实现
#include<iostream>
#include<cmath>
#include"Expression.h"
usingnamespace std;
//----------------------树节点类成员函数
TreeNode::TreeNode(char_data,TreeNode* _left,TreeNode* _right)
{
Data=_data;
left=_left;
right=_right;
}
TreeNode::~TreeNode(){}
charTreeNode::GetData()
{
return Data;
}
voidTreeNode::SetLeft(TreeNode* _left)
{
left=_left;
}
voidTreeNode::SetRight(TreeNode* _right)
{
right=_right;
}
TreeNode*TreeNode::GetLeft()
{
return left;
}
TreeNode*TreeNode::GetRight()
{
return right;
}
voidTreeNode::SetData(char _data)
{
Data=_data;
}
//----------------------------
二叉树几及表达式类成员函数
BinaryTreeAndExpr::BinaryTreeAndExpr():root(NULL)
{
Expr_i=Expr_len=0;
}
BinaryTreeAndExpr::~BinaryTreeAndExpr(){}
voidBinaryTreeAndExpr::Release()
{
if(root!=NULL)
{
ReleaseRecursion(root); //调用释放树的递归函数,实现树的释放
delete(root);
root=NULL;
}
}
voidBinaryTreeAndExpr::ReleaseRecursion(TreeNode* &p)
{
if(p->GetLeft()!=NULL)
{
TreeNode* p1;
p1=p->GetLeft();
ReleaseRecursion(p1);
delete(p1);
}
else if(p->GetRight()!=NULL)
{
TreeNode*p2;
p2=p->GetRight();
ReleaseRecursion(p2);
delete(p2);
}
p=NULL;
}
TreeNode* BinaryTreeAndExpr::GetRoot()
{
return root;
}
voidBinaryTreeAndExpr::ReadExpr(char* E)
{
if(root!=NULL) {Release();root=NULL;}
Expr_i=0;
Expr_len=strlen(E);
if(Expr_len==0) return ;
ReadExprRecursion(root,E);
}
voidBinaryTreeAndExpr::ReadExprRecursion(TreeNode* &p,char* E)
{
if(Expr_i==Expr_len)return ;
p=(TreeNode*)newTreeNode(E[Expr_i++],NULL,NULL);
char temp=p->GetData();
if(!IsOperator(temp)) return ;
else
{
TreeNode* q1,* q2;
ReadExprRecursion(q1,E);
p->SetLeft(q1);
ReadExprRecursion(q2,E);
p->SetRight(q2);
}
}
voidBinaryTreeAndExpr::WriteExpr(char* E)
{
if(root==NULL) {E[0]=‘\0‘;return ;}
WriteExprRecursion(root,E);
}
voidBinaryTreeAndExpr::WriteExprRecursion(TreeNode* p,char* E) //把树中内容转化为字符串
{
char c1,c2,c3[100],c4[100];
if(p->GetLeft()==NULL ||p->GetRight()==NULL)
{
E[0]=p->GetData();
E[1]=‘\0‘;
return ;
}
c1=p->GetLeft()->GetData();
c2=p->GetRight()->GetData();
if(!IsOperator(c1) &&!IsOperator(c2))
{
E[0]=c1;E[1]=p->GetData();E[2]=c2;E[3]=‘\0‘;
}
else if(IsOperator(c1) &&!IsOperator(c2))
{
WriteExprRecursion(p->GetLeft(),c3);
if(Priority(p->GetData(),p->GetLeft()->GetData())>0)
{
E[0]=‘(‘;
for(inti=0;i<strlen(c3);i++) E[i+1]=c3[i];
E[i+1]=‘)‘;
E[i+2]=p->GetData();
E[i+3]=p->GetRight()->GetData();
E[i+4]=‘\0‘;
}
else
{
for(inti=0;i<strlen(c3);i++) E[i]=c3[i];
E[i]=p->GetData();
E[i+1]=p->GetRight()->GetData();
E[i+2]=‘\0‘;
}
}
else if(!IsOperator(c1) &&IsOperator(c2))
{
WriteExprRecursion(p->GetRight(),c3);
if(Priority(p->GetData(),p->GetRight()->GetData())>0) //符号优先级判断,以便于添加括号,以下相同
{
E[0]=p->GetLeft()->GetData();
E[1]=p->GetData();
E[2]=‘(‘;
for(inti=0;i<strlen(c3);i++) E[i+3]=c3[i];
E[i+3]=‘)‘;
E[i+4]=‘\0‘;
}
else
{
E[0]=p->GetLeft()->GetData();
E[1]=p->GetData();
for(inti=0;i<strlen(c3);i++) E[i+2]=c3[i];
E[i+2]=‘\0‘;
}
}
else
{
WriteExprRecursion(p->GetLeft(),c3);
WriteExprRecursion(p->GetRight(),c4);
if(Priority(p->GetData(),p->GetLeft()->GetData())>0)
{
E[0]=‘(‘;
for(inti=0;i<strlen(c3);i++) E[i+1]=c3[i];
E[i+1]=‘)‘;
E[i+2]=‘\0‘;
}
else
{
for(inti=0;i<strlen(c3);i++) E[i]=c3[i];
E[i]=‘\0‘;
}
int j=strlen(E);
E[j]=p->GetData();
if(Priority(p->GetData(),p->GetRight()->GetData())>0)
{
E[j+1]=‘(‘;
for(int i=0;i<strlen(c4);i++)E[j+2+i]=c4[i];
E[j+2+i]=‘)‘;
E[j+3+i]=‘\0‘;
}
else
{
for(inti=0;i<strlen(c4);i++) E[j+1+i]=c4[i];
E[j+1+i]=‘\0‘;
}
}
}
intBinaryTreeAndExpr::Priority(char c1,char c2) //优先级判断函数
{
switch(c1)
{
case ‘+‘:
case ‘-‘:
return -1;
case ‘*‘:
switch(c2)
{
case ‘+‘:
case ‘-‘:
return 1;
}
return -1;
case ‘/‘:
switch(c2)
{
case ‘+‘:
case ‘-‘:
return 1;
}
return -1;
case ‘^‘:
return 1;
}
return 0;
}
boolBinaryTreeAndExpr::IsOperator(char c)
{
return !(c>=97 && c<=122|| c>=48 && c<=57);
}
voidBinaryTreeAndExpr::Assign(char v,int c)
{
AssignRecursion(root,v,c);
}
voidBinaryTreeAndExpr::AssignRecursion(TreeNode* p,char v,int c)
{
if(p!=NULL)
{
if(p->GetData()==v)p->SetData(c+48);
AssignRecursion(p->GetLeft(),v,c);
AssignRecursion(p->GetRight(),v,c);
}
}
BinaryTreeAndExpr*BinaryTreeAndExpr::CompoundExpr(char p,char* E1,char* E2) //构造复合表达式
{
BinaryTreeAndExpr BTAE1,BTAE2,*BTAE3;
BTAE1.ReadExpr(E1);
BTAE2.ReadExpr(E2);
TreeNode* q=(TreeNode*)newTreeNode(p,NULL,NULL);
q->SetLeft(BTAE1.GetRoot());
q->SetRight(BTAE2.GetRoot());
BTAE3=(BinaryTreeAndExpr*)newBinaryTreeAndExpr;
BTAE3->SetRoot(q);
return BTAE3;
}
voidBinaryTreeAndExpr::SetRoot(TreeNode* _root)
{
root=_root;
}
intBinaryTreeAndExpr::Value(char* E) //表达式求值
{
BinaryTreeAndExpr btae;
btae.ReadExpr(E);
returnbtae.ValueRecursion(btae.GetRoot());
}
intBinaryTreeAndExpr::ValueRecursion(TreeNode* p) //表达式求值
{
char c1,c2;
int temp1,temp2;
if(p->GetLeft()==NULL ||p->GetRight()==NULL)
{
c1=p->GetData();
return (c1>=97 &&c1<=122)?0:c1-48;
}
c1=p->GetLeft()->GetData();
c2=p->GetRight()->GetData();
if(!IsOperator(c1) &&!IsOperator(c2))
{
if(c1>=97 &&c1<=122) temp1=0;
else temp1=c1-48;
if(c2>=97 &&c2<=122) temp2=0;
else temp2=c2-48;
returnEvaluation(temp1,p->GetData(),temp2);
}
else if(IsOperator(c1) &&!IsOperator(c2))
{
temp1=ValueRecursion(p->GetLeft());
if(c2>=97 &&c2<=122) temp2=0;
else temp2=c2-48;
returnEvaluation(temp1,p->GetData(),temp2);
}
else if(!IsOperator(c1) &&IsOperator(c2))
{
temp2=ValueRecursion(p->GetRight());
if(c1>=97 &&c1<=122) temp1=0;
else temp1=c1-48;
returnEvaluation(temp1,p->GetData(),temp2);
}
else
{
temp1=ValueRecursion(p->GetLeft());
temp2=ValueRecursion(p->GetRight());
returnEvaluation(temp1,p->GetData(),temp2);
}
}
intBinaryTreeAndExpr::Evaluation(int a,char op,int b)
{
switch(op)
{
case ‘+‘:
return a+b;
break;
case ‘-‘:
return a-b;
break;
case ‘*‘:
return a*b;
break;
case ‘/‘:
return a/b;
break;
case ‘^‘:
return pow(a,b);
break;
}
return 0;
}
3、ExpressionMain.cpp文件的实现(测试文件)
#include<iostream>
#include"Expression.h"
usingnamespace std;
intmain()
{
BinaryTreeAndExpr btae,*btae1;
char E1[100],E2[100],P,V;
int switchs,c,switchs2;
bool run=true,run2=true;
while(run)
{
cout<<"请选择功能,功能如下:"<<endl;
cout<<"1.构造复合表达试并输出相应结果."<<endl;
cout<<"2.输入前缀表达试并构造中缀表达试."<<endl;
cout<<"3.对前缀表达试求值."<<endl;
cout<<"4.退出."<<endl;
cin>>switchs;
switch(switchs)
{
case 4:
run=false;
break;
case 1:
cout<<"请输入相关数据.前缀表达试"<<endl;
getchar();
scanf("%s %c%s",E1,&P,E2);
btae1=BinaryTreeAndExpr::CompoundExpr(P,E1,E2);
while(run2)
{
cout<<"如有变量要赋值请输入1,否则输入2"<<endl;
cin>>switchs2;
if(switchs2==1)
{
cout<<"请输入相关数据."<<endl;
getchar();
scanf("%c%d",&V,&c);
btae1->Assign(V,c);
}
elserun2=false;
}
btae1->WriteExpr(E1);
cout<<"中缀表达试:"<<E1<<endl;
btae1->Release();
delete(btae1);
run2=true;
break;
case 2:
cout<<"请输入相关数据.前缀表达试"<<endl;
cin>>E1;
btae.ReadExpr(E1);
while(run2)
{
cout<<"如有变量要赋值请输入1,否则输入2"<<endl;
cin>>switchs2;
if(switchs2==1)
{
cout<<"请输入相关数据."<<endl;
getchar();
scanf("%c%d",&V,&c);
btae.Assign(V,c);
}
elserun2=false;
}
cout<<"中缀表达试:";
btae.WriteExpr(E2);
cout<<E2<<endl;
run2=true;
break;
case 3:
cout<<"请输入相关数据.前缀表达试"<<endl;
cin>>E1;
btae.ReadExpr(E1);
btae.WriteExpr(E2);
cout<<"中缀表达试为:";
cout<<E2<<endl;
cout<<"计算结果为:";
cout<<BinaryTreeAndExpr::Value(E1)<<endl;
break;
default:
cout<<"你的输入无效!请重新输入."<<endl;
break;
}
btae.Release();
if(run) cout<<endl;
}
return 0;
}
五、 测试结果: