表达式用二叉树表示(共18页)

上传人:4**** 文档编号:48200670 上传时间:2022-01-01 格式:DOCX 页数:18 大小:41.13KB
返回 下载 相关 举报
表达式用二叉树表示(共18页)_第1页
第1页 / 共18页
表达式用二叉树表示(共18页)_第2页
第2页 / 共18页
表达式用二叉树表示(共18页)_第3页
第3页 / 共18页
点击查看更多>>
资源描述
精选优质文档-倾情为你奉上数据结构程序报告(3) 2011.3.29 2. 需求分析:(1)功能:表达式可以用二叉树表示,对于简单的四则运算,请实现以下功能 【1】对于任意给出的前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号),能够在计算机内部构造出一棵表达式二叉树,并且图示出来(图形的形式)。 【2】对于构造好的内部表达式二叉树,按照用户的要求输出相应的前缀表达式(不带括号)、中缀表达式(可以带括号,但不允许冗余括)或后缀表达式(不带括号)。提示:所谓中缀表达式中的冗余括号,就是去掉括号后不影响表达式的计算顺序。例如:“(c+b)+a”中的括号是冗余的,可以表示成不冗余的“c+b+a”。(2)输入输出要求:请输入字符串表达式: 树形二叉树(图形显示) 中缀表达式为:前缀表达式为:后缀表达式为:3. 概要设计:(算法)分成两部分完成:【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 #include #include #include #includeusing namespace std;class TNode/节点类 public:char oper;TNode *left;TNode *right;int s; int t;TNode() left=right=NULL; oper=0;TNode(char op) left=right=NULL; oper=op;bool isOper(char op)/判断是否为运算符char oper=(,),+,-,*,/,;for(int i=0;ileft!=NULL) freeTree(p-left); if(p-right!=NULL) freeTree(p-right); delete(p); coutleft); postOrder(p-right); coutoper; void preOrder(TNode *p) /后序遍历 if(p) coutoper; preOrder(p-left); preOrder(p-right); void inOrder(TNode *p)/中序遍历 if(p) if(p-left) if(isOper(p-left-oper) & getOperOrder(p-left-oper) oper) coutleft); coutleft); coutoper; if(p-right) if(isOper(p-right-oper) & getOperOrder(p-right-oper) oper) coutright); coutright); void ExpTree1(TNode *&p,string str)/后缀表达式生成二叉树stack nodeStack; char temp; int i=0; temp=stri+; while(temp!=0) if(temp!=0&!isOper(temp)/不是运算符,则进栈 p=new TNode(temp);/以temp为结点值构造二叉树结点 nodeStack.push(p); temp=stri+; else p=new TNode(temp); if(nodeStack.size() p-right=nodeStack.top();/若非空则弹栈并设为结点的右孩子 nodeStack.pop(); if(nodeStack.size() p-left=nodeStack.top();/若非空则弹栈并设为结点的左孩子 nodeStack.pop(); nodeStack.push(p); temp=stri+; void ExpTree3(TNode *&p, string str)/前缀表达式生成二叉树 stack nodeStack; char temp; int i=str.size()-1; temp=stri-; while(temp!=0) if(temp!=0&!isOper(temp) p=new TNode(temp);/以temp为内容来建立新的结点 nodeStack.push(p); temp=stri-; else p=new TNode(temp); if(nodeStack.size()/若栈顶指针所指结点左孩子为空 p-left=nodeStack.top(); /则当前结点设置成其左孩子 nodeStack.pop(); if(nodeStack.size()/若栈顶指针所指结点右孩子为空 p-right=nodeStack.top();/则当前结点设置成其右孩子 nodeStack.pop();/栈顶元素左右孩子指针设置完毕弹出 nodeStack.push(p); temp=stri-; void ExpTree2(TNode *&p, string str)/中缀表达式转换成后缀表达式生成二叉树 stack a;char temp;string Postfixexp=;int i=0;temp=stri+; while(temp!=0) if(!isOper(temp) Postfixexp+=temp;temp=stri+; else if(temp=()/进栈 a.push(temp); temp=stri+; else if(temp=) while(a.top()!=()/脱括号 Postfixexp+=a.top(); a.pop();/在碰到开括号和栈为空前反复弹出栈中元素 a.pop(); temp=stri+; else if(temp=+|temp=-|temp=*|temp=/)/出栈while(!a.empty()&a.top()!=(&getOperOrder(a.top()=getOperOrder(temp)/若栈非空栈顶不是左括号且栈顶元素优先级不低于输入运算符时,/将栈顶元素弹出到后缀表达式中,并且str下标加1 Postfixexp+=a.top(); a.pop(); a.push(temp);temp=stri+; while(!a.empty() Postfixexp+=a.top();a.pop();ExpTree1(p,Postfixexp); void count(TNode *p,int &height,int n)/求值函数 if(p-left=NULL&p-right=NULL) if(nheight) height=n; if(p-left!=NULL)count(p-left,height,n+1); if(p-right!=NULL) count(p-right,height,n+1); void paint(TNode *p)/输出函数 int height=0; int h=0; int i;using std:queue;queue aQueue; count(p,height,1);TNode *pointer=p; TNode *lastpointer; if(pointer) pointer-s=1; pointer-t=1; aQueue.push(pointer); while(!aQueue.empty() lastpointer=pointer; pointer=aQueue.front(); aQueue.pop(); if(pointer-sh) couts; if(pointer-t=1) for(i=0;is)-1;i+) couts!=pointer-s)for(i=0;it-1)*(pow(2,height-pointer-s+1)-1)+(pointer-t-1)-1+pow(2,height-pointer-s);i+) cout ; else for(i=0;it-lastpointer-t)*(pow(2,height-pointer-s+1)-1)+(pointer-t-lastpointer-t)-1;i+) cout ; coutoper; if(pointer-left!=NULL) pointer-left-s=pointer-s+1; pointer-left-t=pointer-t*2-1; aQueue.push(pointer-left); if(pointer-right!=NULL) pointer-right-s=pointer-s+1; pointer-right-t=pointer-t*2; aQueue.push(pointer-right); int main() string expression;TNode *tree;coutendlexpression; if(isOper(expression0) ExpTree3(tree,expression); else if(isOper(expression1) ExpTree2(tree,expression); else ExpTree1(tree,expression); paint(tree); coutendl; cout中缀表达式为:; inOrder(tree); coutendl; cout前缀表达式为:; preOrder(tree); coutendl; cout后缀表达式为:; postOrder(tree); coutendl; freeTree(tree); coutendl; system(pause);return 0; 5测试数据:(1)请输入字符串表达式:-+1*234 - + 41 * 2 3中缀表达式为:1+2*3-4前缀表达式为:-+1*234后缀表达式为:123*+4-memory free memory free memory free memory free memory free请按任意键继续.(2)请输入字符串表达式:1+2*3-4 - + 41 * 2 3中缀表达式为:1+2*3-4前缀表达式为:-+1*234后缀表达式为:123*+4-memory free memory free memory free memory free memory free请按任意键继续.(3)请输入字符串表达式:123*+4- - + 41 * 2 3中缀表达式为:1+2*3-4前缀表达式为:-+1*234后缀表达式为:123*+4-memory free memory free memory free memory free memory free请按任意键继续.测试截图:6总结:程序调试中的问题及解决方法:前缀表达式建树,通过入栈出栈操作求出前缀表达式的逆序,针对得到的逆序表达式通过后缀表达式建立二叉树的方法,遇到操作数则入栈,遇到操作符则从栈中弹出两个操作数构建一棵小的二叉树,然后将小树的根节点入栈以便于下次操作。经过循环,小树“长成”大树,表达式读完二叉树即建成。心得体会:由于之前的上机较简单,经过这次作业我才深深感受到编程的滋味,真是苦中有乐,完成之后觉得知识点掌握的更加透彻了,因为有好多问题是不上机根本想不到的,只有经过了实践才会有提高,自己还是太缺乏锻炼,应该多动手编程,从整理思路、编写代码、调试程序修改错误等各方面不断完善自己7使用说明:请输入字符串表达式:可为前缀、中缀、后缀表达式(程序自动判断)专心-专注-专业
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!