《北工大数据结构上机实验报告3.doc》由会员分享,可在线阅读,更多相关《北工大数据结构上机实验报告3.doc(15页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、上机题三报告 姓名: 学号: 完成日期:2015年5月5日题目:表达式可以用表达式二叉树来表示。对于简单的四则运算表达式,请实现以下功能;(1)对于任意给出的前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号),能够在计算机内部构造出一棵表达式二叉树,并且以图示显示出来(字符图或图形的形式)。(2) 对于构造好的内部表达式二叉树,按照用户要求,输出相应的前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号).一、 需求分析1. 输入形式、输入值的范围;输入前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号)2. 输出形式;表达式二叉树,
2、前缀表达式、中缀表达式和后缀表达式。3. 程序功能;用表达式二叉树表示表达式,并转换为前缀表达式、中缀表达式或后缀表达式。4. 测试数据 正确的输入输出: 错误的输入输出: 二、 概要设计1. ADT定义class TNode/节点类开始2. 主程序流程结束输出各类表达式是是将表达式转换为二叉树表达式是否是否为中缀表达式是否为前缀表达式输入表达式是否为后缀表达式否 3. 各程序模块间的调用关系Main() 删除树打印树求前、中、后缀表达式模块求二叉树表达式模块三、 详细设计1. 实现ADT定义的数据类型class TNode/节点类 public:char oper;/数据域,为简便起见,操作
3、数用单个字符代替TNode *left;TNode *right;int s;int t;/计算树的层数使用TNode()/缺省构造函数 left=right=NULL; oper=0; TNode(char op)/赋值构造函数 left=right=NULL; oper=op;2. 算法描述表达式转化为二叉树void pre2tree(TNode *&p, string str)/前缀表达式生成二叉树 碰到操作数则把其值赋给相应的新申请的二叉树结点,地址压栈;碰到操作符则把其值赋给相应的新申请的二叉树,并从栈中弹出两个地址,分别作为其左指针和右指针,然后再把其地址压栈,最后一个地址即为二叉
4、树的根结点地址。void post2tree(TNode *&p,string str)/后缀表达式生成二叉树 /碰到操作数则把其值赋给相应的新申请的二叉树结点,若栈为空则地址压栈,/碰到操作符则把其值赋给相应的新申请的二叉树结点,取栈顶元素,/若当前元素的左孩子为空则设为其左孩子,/左孩子为满则设为其右孩子,开始那个元素地址为根结点地址,开始时用变量root保存。void in2tree(TNode *&p, string str)/中缀表达式转换成后缀表达式生成二叉树 从中缀表达式中自左至右依次读入各个字符。 如果读入操作数,直接输出到后缀表达式。 如果读入的是运算符,并且运算符栈为空,则
5、将该运算符直接进栈;如果栈不为空, 则比较该运算符和栈顶运算符的优先级。若该运算符高于栈顶运算符的优先级,则将该运算符直接进栈; 若该运算符低于或等于栈顶运算符的优先级,则将栈中高于或等于该运算符优先级的元 素依次出栈输出到后缀表达式中,然后再将该运算符进栈。 在碰到开括号和栈为空前反复弹出栈中元素若栈非空栈顶不是左括号且栈顶元素优先级不低于输入运算符时,/将栈顶元素弹出到后缀表达式二叉树表达式转化为表达式void postOrder(TNode *p) /先序遍历 if(p) postOrder(p-left); postOrder(p-right); coutoper; void preO
6、rder(TNode *p) /后序遍历 if(p) coutoper; preOrder(p-left); preOrder(p-right); void inOrder(TNode *p)/中序遍历,同时输出不带冗余括号的中缀表达式 if(p)if(p-left) if(如果当前节点的左子树是运算符,且运算符优先级低于当前运算符,那么左边的表达式要先计算,需要加括号) coutleft); coutleft); coutoper;/输出当前节点 if(p-right) if(如果当前节点的右子树是运算符,且运算符优先级不高于当前运算符,那么右边的表达式要先计算,需要加括号) coutrig
7、ht); coutright); 四、 程序测试五、 用户使用说明运行程序后,按照提示选择表达式类型(-1:前缀表达式;0:中缀表达式;1:后缀表达式)然后输入相应的表达式,回车后可以得到二叉树表达式及出前缀、中缀、后缀表达式六、 源程序#include #include #include #include #includeusing namespace std;class TNode/节点类 public:char oper;/数据域,为简便起见,操作数用单个字符代替TNode *left;TNode *right;int s;int t;/计算树的层数使用TNode()/缺省构造函数 le
8、ft=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); void postOrder(TNode *p) /先序遍历 if(p) postOrder(p-left); postOrder(p-right); coutoper; v
9、oid 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) /
10、如果当前节点的右子树是运算符,且运算符优先级不高于当前运算符,/那么右边的表达式要先计算,需要加括号 if(isOper(p-right-oper)& getOperOrder(p-right-oper)oper) coutright); coutright); void post2tree(TNode *&p,string str)/后缀表达式生成二叉树 /(a)碰到操作数则把其值赋给相应的新申请的二叉树结点,若栈为空则地址压栈,/(b)碰到操作符则把其值赋给相应的新申请的二叉树结点,取栈顶元素,/若当前元素的左孩子为空则设为其左孩子,/左孩子为满则设为其右孩子,开始那个元素地址为根结点地址
11、,开始时用变量root保存。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();/若非空则弹栈并设为结点
12、的右孩子 nodeStack.pop(); if(nodeStack.size() p-left=nodeStack.top();/若非空则弹栈并设为结点的左孩子 nodeStack.pop(); nodeStack.push(p); temp=stri+; void pre2tree(TNode *&p, string str)/前缀表达式生成二叉树/碰到操作数则把其值赋给相应的新申请的二叉树结点,地址压栈;/碰到操作符则把其值赋给相应的新申请的二叉树,并从栈中弹出两个地址,/分别作为其左指针和右指针,然后再把其地址压栈,最后一个地址即为二叉树的根结点地址。stack nodeStack;
13、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
14、.top();/则栈顶指针所指结点设置成当前结点右孩子 nodeStack.pop();/栈顶元素左右孩子指针设置完毕弹出 nodeStack.push(p); temp=stri-; /当栈空且扫描到最后时,树根由P带回void in2tree(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+;
15、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)/若栈非空栈顶不是左括号且栈顶元素优先级不低于输入运算符时,/将栈顶元素弹出到后缀
16、表达式中,并且str下标加 Postfixexp+=a.top(); a.pop(); a.push(temp);temp=stri+; /end while(temp!=0) while(!a.empty() Postfixexp+=a.top();a.pop(); Postfixexp+=0; /coutleft=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(TN
17、ode *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(point
18、er-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; p
19、ointer-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;cout请输入表达式类型,前缀表达式输入-1,中缀表达式输入0 后缀表达式输入1flag; cout请输入字符串表达式:expression; if(flag=-1)/那么是前缀表达式 pre2tree(tree,expression); else if(flag=1)/那么是后缀表达式 post2tree(tree,expression); else /否则中缀表达式 in2tree(tree,expression); paint(tree); coutendl; cout中缀表达式为:; inOrder(tree); coutendl; cout前缀表达式为:; preOrder(tree); coutendl; cout后缀表达式为:; postOrder(tree); coutendl; freeTree(tree); coutendl;return 0;