表达式二叉树Word格式.docx
《表达式二叉树Word格式.docx》由会员分享,可在线阅读,更多相关《表达式二叉树Word格式.docx(14页珍藏版)》请在冰豆网上搜索。
voidpre2tree(Node*&
p,stringstr)//前缀表达式生成二叉树
voidin2tree(Node*&
p,stringstr)//中缀表达式转换成后缀表达式生成二叉树
voidpaint(Node*p)//打印树
voidcount(Node*p,int&
height,intn)//求数的层数,以便与打印树
voidfreeTree(Node*&
p)//递归删除树
intgetOperOrder(charop)//返回运算符op所对应的优先级
2、主程序和各模块的调用
intmain()
stringexpression;
Node*tree;
cout<
<
"
前缀表达式-1中缀表达式0后缀表达式1"
endl;
intflag;
cin>
>
flag;
请输入表达式:
expression;
if(flag==-1)//前缀表达式
pre2tree(tree,expression);
elseif(flag==1)//后缀表达式
post2tree(tree,expression);
else//中缀表达式
in2tree(tree,expression);
paint(tree);
前缀表达式为:
;
preOrder(tree);
中缀表达式为:
inOrder(tree);
后缀表达式为:
postOrder(tree);
freeTree(tree);
return0;
}
三、详细设计
1、表达式转化为二叉树
(1)前缀表达式:
从后往前扫描
①遇到操作数,把它赋给新建立的二叉树结点,入栈;
②遇到运算符,把它赋给新建立的二叉树的节点。
如果栈非空,从栈中弹出一个元素,把栈顶指针所指结点设为当前结点的左孩子,如果栈非空,再从栈中弹出一个元素,把栈顶指针所指结点设置为当前结点的右孩子,然后把当前节点压栈,最后一个元素就是二叉树的根结点。
(2)中缀表达式:
把中缀表达式转换成后缀表达式,然后再生成二叉树。
①定义一个运算符栈,并输入一个中缀表达式,然后从中缀表达式中自左至右依次读入各个字符。
②如果读入操作数,直接输出到后缀表达式。
③如果读入的是运算符,并且运算符栈为空,则将该运算符直接进栈;
如果栈不为空,则
比较该运算符和栈顶运算符的优先级。
▪若该运算符高于栈顶运算符的优先级,则将该运算符直接进栈;
•若该运算符低于或等于栈顶运算符的优先级,则将栈中高于或等于该运算符优先级的元
素依次出栈输出到后缀表达式中,然后再将该运算符进栈。
④如果读入的是开括号“(”,则直接进栈;
如果读入的是闭括号“)”,则一直出栈并输出到后缀表达式,直到遇到一个开括号“(”为止。
开括号“(”和闭括号“)”均不输出到后缀表达式。
⑤重复
(2)(3)(4)步,直到中缀表达式结束,然后将栈中剩余的所有运算符依次出栈。
(3)后缀表达式:
从前往后扫描
①碰到操作数则把它赋给相应的新建立的二叉树结点,若栈为空则入栈,
②碰到运算符则把它赋给相应的新建立的二叉树结点,若当前结点的左孩子为空则设为其左孩子,左孩子为满则设为其右孩子。
开始结点为根结点。
2、二叉树表达式转化为表达式
对二叉树表达式进行前序遍历。
依次输出各结点。
对二叉树表达式进行中序遍历。
如果当前结点的左子树是运算符,且运算符优先级低于当前运算符,那么左边的表达式要先计算,需要加括号,否则直接输出左子树;
如果当前结点的右子树是运算符,且运算符优先级不高于当前运算符,那么右边的表达式要先计算,需要加括号,否则直接输出右子树。
对二叉树表达式进行后序遍历。
四、程序测试
五、源程序
#include<
iostream>
stack>
queue>
string>
#include<
math.h>
usingnamespacestd;
classNode//结点类
{public:
Node(charop){left=right=NULL;
{
charoper[]={'
('
'
)'
+'
-'
*'
/'
^'
for(inti=0;
i<
sizeof(oper);
i++)
{if(op==oper[i])
{
returntrue;
}
returnfalse;
switch(op){
case'
:
return1;
return2;
return3;
return4;
default:
return0;
if(p->
left!
=NULL)
freeTree(p->
left);
right!
right);
delete(p);
{if(p)
{postOrder(p->
postOrder(p->
p->
oper;
{cout<
preOrder(p->
}}
left)
{//如果当前节点的左子树是运算符,且运算符优先级低于当前运算符,
//那么左边的表达式要先计算,需要加括号
if(isOper(p->
left->
oper)&
&
getOperOrder(p->
oper)<
getOperOrder(p->
oper))
{
cout<
("
inOrder(p->
)"
else//否则直接输出左子树
//输出当前节点
right)
{//如果当前节点的右子树是运算符,且运算符优先级不高于当前运算符,
//那么右边的表达式要先计算,需要加括号
if(isOper(p->
right->
=getOperOrder(p->
cout<
else
{stack<
Node*>
nodeStack;
//用于保存节点指针的栈
chartemp;
inti=0;
temp=str[i++];
while(temp!
='
\0'
)
if(temp!
!
isOper(temp))//不是运算符,则进栈
p=newNode(temp);
//以temp为结点值构造二叉树结点
nodeStack.push(p);
//读入下一个
{//如果遇到符号,则出栈,依次设为右节点和左节点
if(nodeStack.size())
p->
right=nodeStack.top();
//若非空则出栈并设为结点的右孩子
nodeStack.pop();
left=nodeStack.top();
//若非空则出栈并设为结点的左孩子
stack<
inti=str.size()-1;
temp=str[i--];
isOper(temp))
{p=newNode(temp);
//以temp为内容来建立新的结点
if(nodeStack.size())//栈非空
{p->
//则栈顶指针所指结点设置成当前结点左孩子
//则栈顶指针所指结点设置成当前结点右孩子
//栈顶元素左右孩子指针设置完毕弹出
stack<
char>
a;
stringPostfixexp="
if(!
isOper(temp))//操作数则直接进数据栈
{Postfixexp+=temp;
elseif(temp=='
)//进栈
a.push(temp);
while(a.top()!
)//脱括号
{
Postfixexp+=a.top();
a.pop();
//在碰到开括号和栈为空前反复弹出栈中元素
}
a.pop();
temp=str[i++];
||temp=='
)//出栈
while(!
a.empty()&
a.top()!
getOperOrder(a.top())>
=getOperOrder(temp))
//若栈非空栈顶不是左括号且栈顶元素优先级不低于输入运算符时
{Postfixexp+=a.top();
a.push(temp);
}//endwhile(temp!
a.empty())
Postfixexp+='
//cout<
Postfixexp;
post2tree(p,Postfixexp);
height,intn){//求树的高度
left==NULL&
right==NULL)
{if(n>
height)
height=n;
count(p->
left,height,n+1);
count(p->
right,height,n+1);
intheight=0;
inth=0;
inti;
usingstd:
queue;
queue<
aQueue;
count(p,height,1);
Node*pointer=p;
Node*lastpointer;
if(pointer)
{pointer->
s=1;
pointer->
t=1;
aQueue.push(pointer);
aQueue.empty())
{lastpointer=pointer;
pointer=aQueue.front();
aQueue.pop();
if(pointer->
s>
h)
{cout<
h=pointer->
s;
t==1)
{for(i=0;
pow(2,height-pointer->
s)-1;
"
elseif(lastpointer->
s!
=pointer->
s){
for(i=0;
(pointer->
t-1)*(pow(2,height-pointer->
s+1)-1)+(pointer->
t-1)-1+pow(2,height-pointer->
s);
else
{for(i=0;
t-lastpointer->
t)*(pow(2,height-pointer->
t)-1;
cout<
pointer->
=NULL){
s=pointer->
s+1;
t=pointer->
t*2-1;
aQueue.push(pointer->
t*2;
}}}
if(flag==-1)//那么是前缀表达式
elseif(flag==1)//那么是后缀表达式
else//否则中缀表达式