表达式用二叉树表示Word格式.docx
《表达式用二叉树表示Word格式.docx》由会员分享,可在线阅读,更多相关《表达式用二叉树表示Word格式.docx(18页珍藏版)》请在冰豆网上搜索。
【1】前缀、中缀、后缀表达式->
二叉树表达式
前缀表达式->
二叉树表达式:
(a)碰到操作数则把其值赋给相应的新申请的二叉树结点,地址压栈;
(b)碰到操作符则把其值赋给相应的新申请的二叉树,并从栈中弹出两个地址,分别作为其右指针和左指针,然后再把其地址压栈,最后一个地址即为二叉树的根结点地址。
中缀表达式->
把中缀表达式转换成后缀表达式,然后再建立二叉树。
后缀表达式->
(a)碰到操作数则把其值赋给相应的新申请的二叉树结点,若栈为空则地址压栈,若非空则取栈顶元素,若栈顶元素的左孩子为空则当前结点设为其左孩子,左孩子为满则设为其右孩子再压栈;
(b)碰到操作数则把其值赋给相应的新申请的二叉树结点,取栈顶元素,若栈顶元素的左孩子为空则设为其左孩子,左孩子为满则设为其右孩子开始那个元素地址为根结点地址,开始时用变量root保存。
【1】二叉树表达式->
前缀、中缀、后缀表达式
二叉树表达式->
前缀表达式:
对二叉树表达式进行前序遍历。
中缀表达式:
对二叉树表达式进行中序遍历,若结点操作符的优先级高于其左或右子树,在打印相应的子树之前先打印开括号,在打印相应的子树最后在打印一个闭括号。
后缀表达式:
对二叉树表达式进行后序遍历。
建立表达式树就是建立树中的每一个结点,将每一个结点链接起来就是整棵树。
而在建立深度低的结点时要将其左右指针指向之前建立的深度比它高一级的结点(如’*’要指向’2’和’3’,而’+’又要指向’*’)。
这样我们可以用栈来存放每次建立的结点,按照优先级(表达式为中缀型)或顺序扫描表达式(表达式为波兰式与逆波兰式)建立每一个结点。
建立结点的顺序即为表达式求值的顺序。
如果扫描到操作数则直接新建一个左右指针为空的结点,并压入结点栈中(存放结点指针)。
遇到运算符时首先新建一个结点,然后从栈中依次弹出两个结点,并让新建立的结点的左右指针域指向它们。
当所有结点建立完毕时,如果表达式没有错误(这里假设输入表达式正确),这时栈中应该只剩下一个结点,它就是所建立的表达式的根结点。
4.详细设计:
(具体方法)
首先创建一个节点类TNode:
包含操作符oper、左孩子left、右孩子right,isOper()判断是否为操作符,getOperOrder()返回运算符op所对应的优先级,freeTree()程序结束销毁二叉树,postOrder()先序遍历,preOrder()后序遍历,inOrder()中序遍历,ExpTree1()后缀表达式生成二叉树,ExpTree3()前缀表达式生成二叉树,ExpTree2()中后缀表达式生成二叉树,count()求值函数,paint()输出函数
附程序:
#include<
iostream>
stack>
queue>
string>
#include<
math.h>
usingnamespacestd;
classTNode//节点类
{public:
charoper;
TNode*left;
TNode*right;
ints;
intt;
TNode()
{left=right=NULL;
oper=0;
}
TNode(charop)
oper=op;
}};
boolisOper(charop)//判断是否为运算符
{
charoper[]={'
('
'
)'
+'
-'
*'
/'
^'
};
for(inti=0;
i<
sizeof(oper);
i++)
{if(op==oper[i])
{
returntrue;
}}
returnfalse;
intgetOperOrder(charop)//返回运算符op所对应的优先级
{switch(op)
{case'
:
return1;
case'
return2;
return3;
return4;
default:
//定义在栈中的右括号和栈底字符的优先级最低
return0;
}}
voidfreeTree(TNode*&
p)//释放树
{if(p->
left!
=NULL)
freeTree(p->
left);
if(p->
right!
right);
delete(p);
cout<
<
"
Memoryfree"
;
}
voidpostOrder(TNode*p)//先序遍历
{if(p)
{postOrder(p->
postOrder(p->
cout<
p->
oper;
voidpreOrder(TNode*p)//后序遍历
{cout<
preOrder(p->
voidinOrder(TNode*p)//中序遍历
left)
{if(isOper(p->
left->
oper)
&
&
getOperOrder(p->
<
getOperOrder(p->
oper))
{cout<
("
inOrder(p->
cout<
)"
}else{
}}
if(p->
right)
right->
=getOperOrder(p->
}}}}
voidExpTree1(TNode*&
p,stringstr)//后缀表达式生成二叉树
{stack<
TNode*>
nodeStack;
chartemp;
inti=0;
temp=str[i++];
while(temp!
='
\0'
)
{if(temp!
!
isOper(temp))//不是运算符,则进栈
{p=newTNode(temp);
//以temp为结点值构造二叉树结点
nodeStack.push(p);
temp=str[i++];
else
{p=newTNode(temp);
if(nodeStack.size())
{p->
right=nodeStack.top();
//若非空则弹栈并设为结点的右孩子
nodeStack.pop();
}
left=nodeStack.top();
//若非空则弹栈并设为结点的左孩子
nodeStack.push(p);
temp=str[i++];
}}}
voidExpTree3(TNode*&
p,stringstr)//前缀表达式生成二叉树
{stack<
inti=str.size()-1;
temp=str[i--];
isOper(temp))
//以temp为内容来建立新的结点
temp=str[i--];
{p=newTNode(temp);
if(nodeStack.size())//若栈顶指针所指结点左孩子为空
{p->
//则当前结点设置成其左孩子
}if(nodeStack.size())//若栈顶指针所指结点右孩子为空
{p->
//则当前结点设置成其右孩子
//栈顶元素左右孩子指针设置完毕弹出}
nodeStack.push(p);
temp=str[i--];
voidExpTree2(TNode*&
p,stringstr)//中缀表达式转换成后缀表达式生成二叉树
{stack<
char>
a;
chartemp;
stringPostfixexp="
inti=0;
temp=str[i++];
{if(!
{Postfixexp+=temp;
elseif(temp=='
)//进栈
{a.push(temp);
temp=str[i++];
elseif(temp=='
){
while(a.top()!
)//脱括号
{Postfixexp+=a.top();
a.pop();
//在碰到开括号和栈为空前反