应用二叉树解析XML表示的函数计算表达式

应用二叉树解析XML表示的函数计算表达式
应用二叉树解析XML表示的函数计算表达式

应用二叉树解析XML 表示的函数计算表达式

XForms 的函数计算表达式简介

XForms 是用于 XML 数据处理的 Web 表单规 , 它允许您将表单的用途和外观

分开?目前 W3C 组织正在审查 XForms 1.1 的候选工作草案(1.0 是正式的

Internet 推荐标准)。IBM? Lotus Forms ( 电子表单领域的杰出产品之一 ) 就是基于 XForms 和 XFDL (Extensible Forms Description Language) 语言的,它把 XForms 强大的数据处理能力和 XFDL 语言丰富的表示能力紧密的结合在一起。

XForms 的数据模型(Data Model)封装了对表单数据的一些逻辑处理操作。如清单 1 所示,xforms:bind 元素拥有一个 calculate 属性。该属性通过函数计算表达式来实现表单数据的处理逻辑。

清单 1. XForms 的函数计算表达式

nodeset="instance('INSTANCE')/P001/VarianceMeals">

nodeset="instance('INSTANCE')/P001/minAccount">

在清单 2 中,我们简单介绍了另一种 XML 表示的函数计算表达式,其应用于一款基于 XML 语法的电子表单产品中。窥豹可见一斑,本文同样适用于其它基于XML 语法的函数计算表达式。

清单 2. XForms 的函数计算表达式

If DateTo < DateFrom Then False With Alert</p><p>"This date must come after the date you have entered in the Date From field"</p><p>End</plainText></p><p></calculation></p><p><calculation></p><p><func name="Min"></p><p><func name="Abs"></p><p><cell name="Summary" /></p><p></func></p><p><func name="Subtract"></p><p><cell name="Demo1"></p><p><cell name="Demo2"></p><p></func></p><p><number value="100" /></p><p></func></p><p><plainText>Min(Abs(Summary),Demo1-Demo2, 100)</plainText></p><p></calculation></p><p>…</p><!--/p2--><!--p3--><p>在清单 2 中 <func> 标签用以标识函数或操作符。其 name 的属性值既是函数或操作符的名称。<cell> 标签,读者可以理解为用以标识函数计算表达式中的变量;而 <number>,<string> 等标签则是标识函数计算表达式中的常量容。</p><p>当我们需要解析函数计算表达式的时候 , 我们都有什么办法呢?比如在上面的代码片段中,直接解析 <plainText> 元素的容似乎是一个办法。直接解析</p><p><plainText>Min(Abs(Summary), Demo1-Demo2, 100)</plainText> 就已经得到了正确的结果。然而,解析含有大量嵌套的条件判断语句的函数计算表达式,如解析第一个 <plainText> 元素中的容就变得非常困难了。当我们要想进一步分析并处理 <plainText> 元素中的函数计算表达式的时候,表达式已经丢失了很多重要的原始信息(比如说类型信息),这样处理起来就难上加难了。有什么更好的办法么?我们可以尝试解析除了 <plainText> 元素以外的以</p><p><calculation> 元素为根的 XML 代码片段中的信息。</p><p>回页首</p><p>建立用以解析函数计算表达式的二叉树数据结构模型</p><p>仔细分析一下清单 2 所示的函数计算表达式,我们不难得出其数据结构模型,如图 1 所示 :</p><p>图 1. 函数计算表达式的树模型</p><p>我们可以通过 XML 解析器(DOM, SAX, StAX etc.)解析 XML 得到基于以树为数据结构的存模型。但是遍历以二叉树为数据结构的存模型要比以树为数据结构的存模型更方便明了(读者更为熟悉)。在图 2 中,我们把以树为数据结构的模型转换为对应的以二叉树为数据结构的模型(结点的孩子结点为该结点的左孩子结点;结点的兄弟结点为该结点的右孩子结点)。</p><p>图 2. 函数计算表达式的二叉树(BinTree)模型</p><!--/p3--><!--p4--><p>清单 3. XML 结点对应的存模型</p><p>public class CalNode {</p><p>public CalNode left;</p><p>public CalNode right;</p><p>private String value;</p><p>private String type; // Three kinds of type: cell, func, const</p><p>public CalNode(String type, String value) {</p><p>this.type = type;</p><p>this.value = value;</p><p>}</p><p>public CalNode(CalNode left, String type, String value, CalNode right) {</p><p>this.left = left;</p><p>this.type = type;</p><p>this.value = value;</p><p>this.right = right;</p><p>}</p><p>public String getValue() {</p><p>return value;</p><p>}</p><p>public void setValue(String value) {</p><p>this.value = value;</p><p>}</p><p>public String getType() {</p><p>return type;</p><p>}</p><p>}</p><!--/p4--><!--p5--><p>在清单 3 中,我们创建 XML 结点对应的存模型类—— CalNode。该类非常简单,包括左孩子结点,右孩子结点,结点本身的值以及结点的类型。根据这种函数计算表达式所涉及的 XML 元素的标签值(tag)结点的类型可分为三种:func,函数和操作符;cell,函数计算表达式中的变量 ; const, 表达式中所涉及的字符串或数值常量(当我们遍历二叉树的时候,我们需要根据结点的类型进行相应的逻辑处理。)拿上面的例子来说,当解析 <func name=”Min”> 的时候,就生成了一个值为 Min, 类型是 func 的 calNode 类的实例对象。</p><p>清单 4. 应用 DOM 解析 XML 生成以二叉树为数据结构的存模型</p><p>private CalNode createCalBinTree(Node root) {</p><p>String rootName = ParserHelper.validateSID(XMLUtil.getAttribute( (Element) root, Constants.ATTR_NAME));</p><p>//For <number value=""/></p><p>and <string value="xxxx"/></p><p>elements within <func></p><p>if (StringHelper.isEmpty(rootName)) { //isEmpty 方法判断是否为空</p><p>rootName = ParserHelper.validateComputeContent(XMLUtil.getAttribute( (Element) root, Constants.ATTR_VALUE));</p><p>}</p><p>String type = root.getNodeName(); // 结点的类型</p><p>if (!CalConstants.CELL.equals(type)</p><p>&& !CalConstants.FUNC.equals(type))</p><p>type = CalConstants.CONST; // 如果类型不是 func 或 cell,则设置为const</p><p>CalNode rootNode = new CalNode(null, type, rootName, null); // 生成CalNode 类的实例对象</p><p>Node firstNode = root.getFirstChild(); // 拿到结点 root 的第一个孩子(DOM API)</p><p>if (firstNode != null){</p><p>// 递归遍历第一个孩子结点,生成 CalNode 的实例对象。</p><p>CalNode firstCalNode = createCalBinTree(firstNode);</p><p>rootNode.left = firstCalNode; // 把第一个孩子结点设置为该结点的左孩子结点</p><p>// 考虑该结点的其它孩子结点</p><p>Node pNode = firstNode;</p><p>CalNode qCalNode = firstCalNode;</p><p>while (pNode.getNextSibling() != null) {</p><p>Node nextNode = pNode.getNextSibling();</p><p>if (nextNode != null){</p><p>CalNode nextCalNode = createCalBinTree(nextNode); // 递归遍历其它孩子结点</p><p>qCalNode.right = nextCalNode; // 设置为其上一个兄弟结点的右孩子结点</p><!--/p5--><!--p6--><p>//loop for org.w3c.dom.Node</p><p>pNode = nextNode;</p><p>//loop for CalNode</p><p>qCalNode = nextCalNode;</p><p>}</p><p>}</p><p>}</p><p>return rootNode;</p><p>private TreeNode<Elem ></p><p>GoFarLeft(TreeNode<Elem> t, Stack<TreeNode<Elem> > S) {</p><p>if (t == null)</p><p>return null;</p><p>while (t.left != null){</p><p>S.push(t);</p><p>t = t.left;</p><p>}</p><p>return t;</p><p>}</p><p>// inorder iterative scan</p><p>private void Inorder_I(TreeNode<Elem> t, void visit(Elem c)){ Stack<TreeNode<Elem>> S=new Stack<TreeNode<Elem>>();</p><p>t = GoFarLeft(t,S);</p><p>// continue until t is NULL</p><p>while(t != null){</p><p>visit(t.data);</p><p>if (t.right!=null)</p><!--/p6--><!--p7--><p>t = GoFarLeft(t.right,S); else if ( !S.isEmpty( )) t = S.pop();</p><p>else</p><p>t = null; // we are done }</p><!--/p7--><!--p8--><p>图 3. 解析处理函数计算机表达式的流程图</p><p>如上图所示,流程图根据 rootNode 的值是否为函数,操作符而分为三部分。第一部分就是对函数计算表达式中的函数进行处理。第二部分就是递归处理表达式中的操作符。最后处理表达式中的常量和变量。</p><p>其源代码如下:</p><!--/p8--><!--p9--><p>清单 6. 中序非栈递归遍历并解析函数表达式</p><p>public void createXFormsBinding(CalNode rootNode, StringBuffer str) { // 参数 str 用来存放解析结果</p><p>if (rootNode == null) { // 结点为空,返回</p><p>return;</p><p>}</p><p>String foName = rootNode.getValue(); // 获取结点的值</p><p>// 如果类型是 func , 并且是合法的函数</p><p>if ( rootNode.getType().equals(CalConstants.FUNC) &&</p><p>FunctionConstants.isValidFNFunction(foName)) {</p><p>if (rootNode.left == null) {</p><p>// 该结点的左孩子结点是空的时候,逻辑操作如下:</p><p>if (FunctionConstants.NOW.equals(foName)) {</p><p>str.append("now()");</p><p>} else if (…) {</p><p>…</p><p>}</p><p>return;</p><p>} else { // 该结点是带有参数的函数</p><p>// 特殊函数的处理(如:IfThen 和 IFT)</p><p>if (FunctionConstants.IFTHEN.equals(foName)</p><p>|| FunctionConstants.IFT.equals(foName)) {</p><p>…</p><p>return;</p><p>}else if(…){ // 其它特殊的函数的处理逻辑</p><p>…</p><p>return;</p><p>}else { // 非特殊函数的处理</p><p>str.append(FunctionConstants.getMappedFunction(foName)</p><p>+ "("); //$NON-NLS-1$ // 加左括号</p><p>// 递归调用,用以处理函数的参数</p><p>createXFormsBinding(rootNode.left, str);</p><p>}</p><p>}</p><p>// 右孩子信息</p><p>CalNode p = rootNode.left;</p><p>CalNode q = null;</p><p>if(p!=null)</p><p>q = rootNode.left.right;</p><p>while (p != null && q != null) {</p><p>str.append(","); //$NON-NLS-1$ // 参数用逗号分隔</p><p>createXFormsBinding(q, str); // 递归调用,处理该参数</p><!--/p9--><!--p10--><p>q = q.right;</p><p>}</p><p>// 加右括号</p><p>str.append(")"); //$NON-NLS-1$</p><p>// 如果类型是 func , 并且是合法的操作符</p><p>} else if (rootNode.getType().equals(CalConstants.FUNC) &&</p><p>OperatorConstants.isValidFNOperator(foName)) {</p><p>// 若没有左孩子结点,返回</p><p>if(rootNode.left==null){</p><p>return;</p><p>}</p><p>// 如果是乘,除以及求模等操作符,需要进一步判断,根据需要对左右孩子树加括号</p><p>if (OperatorConstants.DIV.equals(foName)</p><p>|| OperatorConstants.MULTIPLY.equals(foName)||…) {</p><p>// 处理操作符的左孩子树</p><p>if (OperatorConstants.isValidFNOperator(rootNode.left</p><p>.getValue())&& …) {</p><p>str.append("("); //$NON-NLS-1$</p><p>createXFormsBinding(rootNode.left, str);</p><p>str.append(")"); //$NON-NLS-1$</p><p>} else {</p><p>createXFormsBinding(rootNode.left, str);</p><p>}</p><p>// 取操作符的名字</p><p>str.append(" " +</p><p>OperatorConstants.getMappedXFDLOperator(foName) + " ");</p><p>// 处理操作符的右孩子树</p><p>if (rootNode.left.right != null</p><p>&& OperatorConstants.isValidFNOperator(rootNode.left.right</p><p>.getValue())&& …) {</p><p>str.append("("); //$NON-NLS-1$</p><p>createXFormsBinding(rootNode.left.right, str);</p><p>str.append(")"); //$NON-NLS-1$</p><p>} else {</p><p>createXFormsBinding(rootNode.left.right, str);</p><p>}</p><p>}</p><p>// 对 % 操作符的逻辑处理</p><p>else if (OperatorConstants.PERCENT.equals(foName)) {</p><p>…</p><p>}</p><p>// 对其它特殊操作符的逻辑处理</p><p>else if (OperatorConstants.XXX.equals(foName)||…) {</p><!--/p10--><!--p11--><p>…</p><p>}</p><p>// 对非 func 类型进行处理(cell 类型以及表达式中的常量)</p><p>else {</p><p>if (rootNode.getType().equals(CalConstants.CELL)) {</p><p>// 转成 XPATH 表达式的中结点</p><p>str.append("../" + foName); //$NON-NLS-1$</p><p>} else { // 表达式中的常量处理</p><p>str.append("'" + foName + "'"); //$NON-NLS-1$ //$NON-NLS-2$</p><p>}</p><p>}</p><p>}</p><p>在清单 6 中,我们比较详尽的给出了中序非栈递归遍历二叉树的算法,根据CalNode 实例对象的不同类型分别进行处理。 func 类型既可能是函数,也可能是操作符。我们需要加以判断进而分别处理。在函数或操作符的处理逻辑中,又存在一些特殊的函数(比如说条件判断 IfThen 等函数)和一些特殊的操作符(比如%操作符),我们同样需要区分处理。对于 cell 类型的 CalNode 类的实例对象,他们是函数计算表达式中的变量,在解析的过程中需要根据实际的逻辑需要,执行相应的逻辑操作。本文中把其转换为 Xpath 的结点形式。比如表达式中 Summary 结点被转为: ../Summary。const 类型的常量的逻辑处理相对比较容易。在本文中,仅仅是把常量类型加上单引号。</p><p>如果执行此函数,Min(Abs(Summary),Demo1-Demo2, 100) 这样的函数计算表达式可能会被转换为IBM? Lotus Forms 中如清单 7 所示的 XForms 绑定语句中calculate 属性的值:</p><p>清单 7. 生成 XForms 的函数计算表达式</p><p><xforms:bind calculate=" min (abs(../Summary), ../Demo1 - ../Demo2, ‘100’ )"</p><!--/p11--><!--p12--><p>算表达式转换为IBM? Lotus Forms 产品所支持的函数计算表达式(即:XForms 的函数计算表达式)。</p><p>如果处理逻辑非常复杂,比如,需要结合父结点来处理子结点的逻辑。建议在清单 3 所示的存模型中加入一个指向父结点的句柄(线索二叉树)。除此之外,本文所说的方法还可以应用到更多的应用场景,在此不一一叙述。</p><!--/p12--><!--rset--><h2>表达式二叉树·实验代码</h2><p>实验:表达式二叉树 实验要求: 建立表达式二叉树,并打印(可逆时针旋转90度打印,也可尝试正向打印) 以中缀表达式a*b+(c-d)/e-f 为例,建立以"-"号为根的表达式二叉树。 提示:若直接利用中缀表达式建立困难,可先将中缀表达式转化为后缀表达式(可利用栈中的中缀到后缀转化程序实现中缀表达式到后缀表达式的转换,再根据后缀表达式建立表达式二叉树,可参考栈中后缀表达式计算方法)。 实验代码: #include <iostream> #include <stack> #include <string> #include <queue> #include <vector> using namespace std; class tnode; void buildexptree(const string &exp); void printexptree(); int judgerank(char ch); bool isoperator(char ch); void test(); void setxy(tnode *tn, int y); int X = 0; int Y = 0; int depth = 0; vector<tnode*>vt; class tnode{ public: char nodeV alue; int x, y; tnode *left; tnode *right;</p><p>tnode(){ x = 0; y = 0; } tnode(char &item, tnode *lptr = NULL, tnode *rptr = NULL): nodeV alue(item), left(lptr), right(rptr){ x = 0; y = 0; } }; tnode *myNode; bool cmp(tnode *t1, tnode *t2){ if(t1->y != t2->y) return (t1->y) > (t2->y); return (t1->x) < (t2->x); } class zpair{ //将operator和rank打包为一体,临时存储在stk2中public: char op; int rank; zpair(){} zpair(char _op, int _rank){ op = _op; rank = _rank; } }; int judgerank(char ch){ if(ch == '(') return -1; if(ch == '+' || ch == '-') return 1; if(ch == '*' || ch == '/') return 2; return 0; } bool isoperator(char ch){ if(ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '*' || ch == '/') return true; else return false; }</p><h2>波兰算法求二叉树表达式的值</h2><p>逆波兰表达式 问题描述 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4。本题求解逆波兰表达式的值,其中运算符包括+ - * / 四个。 输入数据 输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数 输出要求 输出为一行,表达式的值。 输入样例 * + 11.0 12.0 + 24.0 35.0 输出样例 1357.000000 #include <stdio.h> #include <stdlib.h> #include "string.h" struct node { char data[20]; node *lChild,*rChild; }; int k=0; doubleCalculateEepress(node *root) { k++; if(root->data[0]>='0'&&root->data[0]<='9') return atof(root->data); else { switch(root->data[0]) { case '+': return CalculateEepress(root->lChild)+CalculateEepress(root->rChild); case '-': return CalculateEepress(root->lChild)-CalculateEepress(root->rChild); case '*': return CalculateEepress(root->lChild)*CalculateEepress(root->rChild); case '/': return CalculateEepress(root->lChild)/CalculateEepress(root->rChild); } } } voidconstructExpress(node *&root) { char sub[20];</p><h2>数据结构第六章树和二叉树习题及答案</h2><p>习题六树和二叉树 一、单项选择题 1.以下说法错误的是() A. 树形结构的特点是一个结点可以有多个直接前趋 B. 线性结构中的一个结点至多只有一个直接后继 C. 树形结构可以表达(组织)更复杂的数据 D. 树(及一切树形结构)是一种”分支层次”结构 E. 任何只含一个结点的集合是一棵树 2. 下列说法中正确的是() A. 任何一棵二叉树中至少有一个结点的度为2 B. 任何一棵二叉树中每个结点的度都为2 C. 任何一棵二叉树中的度肯定等于2 D. 任何一棵二叉树中的度可以小于2 3. 讨论树、森林和二叉树的关系,目的是为了() A. 借助二叉树上的运算方法去实现对树的一些运算 B. 将树、森林按二叉树的存储方式进行存储 C. 将树、森林转换成二叉树 D. 体现一种技巧,没有什么实际意义4.树最适合用来表示() A. 有序数据元素 B .无序数据元素 C.元素之间具有分支层次关系的数据 D .元素之间无联系的数据 5.若一棵二叉树具有10个度为2的结点,5个度为1的结点,则度为0的结点个数是()A.9 B .11 C .15 D .不确定 6. 设森林F中有三棵树,第一,第二,第三棵树的结点个数分别为M1, M2和M3与森林F 对应的二叉树根结点的右子树上的结点个数是()。 A.M1 B .M1+M2 C .M3 D .M2+M3 7.一棵完全二叉树上有1001个结点,其中叶子结点的个数是() A.250 B .500 C .254 D .505 E .以上答案都不对 8. 设给定权值总数有n 个,其哈夫曼树的结点总数为() A. 不确定 B . 2n C . 2n+1 D . 2n-1 9.二叉树的第I 层上最多含有结点数为() I I-1 I-1 I A.2I B .2 I-1 -1 C .2 I-1 D .2 I -1 10.一棵二叉树高度为h, 所有结点的度或为0,或为2,则这棵二叉树最少有()结点A.2h B .2h-1 C .2h+1 D .h+1 11. 利用二叉链表存储树,则根结点的右指针是()。 A.指向最左孩子 B .指向最右孩子 C .空D .非空 12.已知一棵二叉树的前序遍历结果为为()。 A.CBEFDA B .FEDCBA 13.已知某二叉树的后序遍历序列是()。 ABCDEF中序遍历结果 为 C .CBEDFA D dabec, 中序遍历序列是 CBAEDF则后序遍历的结 果 .不定 debac , 它的前序遍历是</p><h2>第6章树和二叉树习题</h2><p>第六章 树和二叉树 一、选择题 1.算术表达式a+b*(c+d/e )转为后缀表达式后为( B ) A .ab+cde/* B .abcde/+*+ C .abcde/*++ D .2. 设有一表示算术表达式的二叉树(见下图), 它所表示的算术表达式是( C ) A. A*B+C/(D*E)+(F-G) B. (A*B+C)/(D*E)+(F-G) C. (A*B+C)/(D*E+(F-G )) D. A*B+C/D*E+F-G 3. 设树T 的度为4,其中度为1,2,3和4的结点个数分别为4,2,1 ,1 则T 中的叶子数为( D ) A .5 B .6 C .7 D .8 4. 在下述结论中,正确的是( D ) ①只有一个结点的二叉树的度为0; ②二叉树的度为2; ③二叉树的左右子树可任意 交换; ④深度为K 的完全二叉树的结点个数小于或等于深度相同的满二叉树。 A .①②③ B .②③④ C .②④ D .①④ 5. 设森林F 对应的二叉树为B ,它有m 个结点,B 的根为p,p 的右子树结点个数为n,森林F 中第一棵树的结点个数是( A ) A .m-n B .m-n-1 C .n+1 D .条件不足,无法确定 6.若一棵二叉树具有10个度为2的结点,5个度为1的结点,则度为0的结点个数是( B ) A .9 B .11 C .15 D .不确定 7.设森林F 中有三棵树,第一,第二,第三棵树的结点个数分别为M1,M2和M3。与森林F 对应的二叉树根结点的右子树上的结点个数是( D )。 A .M1 B .M1+M2 C .M3 D .M2+M3 8.一棵完全二叉树上有1001个结点,其中叶子结点的个数是( E ) A . 250 B . 500 C .254 D .505 E .以上答案都不对 9. 有关二叉树下列说法正确的是( B ) A .二叉树的度为2 B .一棵二叉树的度可以小于2 C .二叉树中至少有一个结点的度为2 D .二叉树中任何一个结点的度都为2 10.二叉树的第I 层上最多含有结点数为( C ) A .2I B . 2I-1-1 C . 2I-1 D .2I -1 11. 一个具有1025个结点的二叉树的高h 为( C ) A .11 B .10 C .11至1025之间 D .10至1024之间 12.一棵二叉树高度为h,所有结点的度或为0,或为2,则这棵二叉树最少有( B )结点 A .2h B .2h-1 C .2h+1 D .h+1 13. 一棵树高为K 的完全二叉树至少有( C )个结点 A .2k –1 B. 2k-1 –1 C. 2k-1 D. 2 k 14.对二叉树的结点从1开始进行连续编号,要求每个结点的编号大于其左、右孩子的编号,同一结点的左右孩子中,其左孩子的编号小于其右孩子的编号,可采用( C )次序的遍历 实现编号。 A .先序 B. 中序 C. 后序 D. 从根开始按层次遍历 15.一棵二叉树的前序遍历序列为ABCDEFG ,它的中序遍历序列可能是( B )</p><h2>算术表达式与二叉树</h2><p>目录 一、系统开发的背景 (1) 二、系统分析与设计 (1) (一)系统功能要求 (1) (二)系统模块结构设计 (1) 三、系统的设计与实现 (3) (一)二叉树的遍历 (3) (二)算术表达式求值 (5) 四、系统测试 (9) (一)测试二叉树遍历函数 (9) (二)测试算术表达式求值函数 (10) 五、总结 (10) 六、附件(代码、部分图表) (10) (一)程序代码 (10) (二)实验截图 (15)</p><p>算术表达式与二叉树 一、系统开发的背景 为了方便进行基本的算术运算,减轻对数字较大的数操作时所带来的麻烦,及其在运算过程中错误的避免。因此设计算术表达式与二叉树的程序来解决此问题。 二、系统分析与设计 (一)系统功能要求 由于一个表达式和一棵二叉树之间,存在着自然的对应关系。遍写一个程序,实现基于二叉树表示的算术表达式的操作。算术表达式内可以含有变量(a~z)、常量(0~9)和二元运算符(+,-,*,/,^(乘幂))。 具体实现以下操作: 1以字符序列的形式输入语法正确的前缀表达式并构造表达式。 2用带括弧的中缀表达式输出表达式。 3实现对变量V的赋值(V=c),变量的初值为0。 4对算术表达式E求值。 (二)系统模块结构设计 通过对系统功能的分析,基于二叉树表示的算术表达式的功能 如图(1)所示。</p><p>图1:基于二叉树表示的算术表达式的功能图 通过上图的功能分析,把整个系统划分为主要的两大个模块: 1、将语法正确的前缀表达式用二叉树的遍历转换成相应的遍历序列,必要时可以求出此二叉树的结点数及其树的深度。该模块借助函数BiTree Create(BiTree T)创建二叉树,void Preorder(BiTree T) 先序遍历, void InOrder(BiTree T)中序遍历,void PostOrder(BiTree T)后序遍历,int Sumleaf(BiTree T)统计叶结点的数目,int Depth(BiTree T)二叉树的深度6个函数联合来实现; 2、计算中序遍历所得的算术表达式的值。其中先要将扫描得到的中缀表达式转换为后缀表达式,然后利用栈的初始化,进栈与取栈顶元素操作进行对后缀表达式进行计算。该模块借助函数void InitStack(SeqStack *S)初始化栈,int PushStack(SeqStack *S,char e)进栈,int GetTop(SeqStack</p><h2>二叉树求节点数</h2><p>二叉树求节点数 #include #include #include //函数状态码定义 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -1 #define INFEASIBLE -2 #define NULL 0 typedef int Status; typedef int TElemType; typedef struct BiTNode{ TElemType data; struct BiTNode *lchild,*rchild; }BitNode, *BiTree; Status PrintTElem(TElemType e) { printf("%d ",e); return OK; } Status CreateBiTree(BiTree &T){ TElemType e; scanf("%d",&e); if(e==0 )T=NULL; else{ T=(BiTree)malloc(sizeof(BiTNode)); if(!T)exit(OVERFLOW); T->data=e; CreateBiTree(T->lchild); CreateBiTree(T->rchild);</p><p>} return OK; } Status PreOrderTraverse(BiTree T,Status(*visit)(TElemType)) { if(T){ if( (*visit)(T->data) ) if( PreOrderTraverse(T->lchild,(*visit)) ) if( PreOrderTraverse(T->rchild,(*visit)) ) return OK; return ERROR; } else return OK; } int NodeCount(BiTree T){ //递归法统计所有结点的个数 int n; if(T==NULL)n=0; else n=1+NodeCount(T->lchild)+NodeCount(T->rchild); return n; } void main() { BiTree T; CreateBiTree(T); printf("二叉树T的先序输出序列为:"); PreOrderTraverse(T,PrintTElem); printf("\n"); printf("二叉树T的叶子节点数为 %d\n",NodeCount(T)); }</p><h2>数据结构实验二叉树</h2><p>实验六:二叉树及其应用 一、实验目的 树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。 二、问题描述 首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。 如算术表达式:a+b*(c-d)-e/f 三、实验要求 如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算统计叶子结点的个数。求二叉树的深度。十进制的四则运算的计算器可以接收用户来自键盘的输入。由输入的表达式字符串动态生成算术表达式所对应的二叉树。自动完成求值运算和输出结果。四、实验环境 PC微机 DOS操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、根据二叉树的各种存储结构建立二叉树; 2、设计求叶子结点个数算法和树的深度算法; 3、根据表达式建立相应的二叉树,生成表达式树的模块; 4、根据表达式树,求出表达式值,生成求值模块; 5、程序运行效果,测试数据分析算法。 六、测试数据 1、输入数据:*(+)3 正确结果: 2、输入数据:(1+2)*3+(5+6*7);</p><p>正确输出:56 七、表达式求值 由于表达式求值算法较为复杂,所以单独列出来加以分析: 1、主要思路:由于操作数是任意的实数,所以必须将原始的中缀表达式中的操作数、操作符以及括号分解出来,并以字符串的形式保存;然后再将其转换为后缀表达式的顺序,后缀表达式可以很容易地利用堆栈计算出表达式的值。 例如有如下的中缀表达式: a+b-c 转换成后缀表达式为: ab+c- 然后分别按从左到右放入栈中,如果碰到操作符就从栈中弹出两个操作数进行运算,最后再将运算结果放入栈中,依次进行直到表达式结束。如上述的后缀表达式先将a 和b 放入栈中,然后碰到操作符“+”,则从栈中弹出a 和b 进行a+b 的运算,并将其结果d(假设为d)放入栈中,然后再将c 放入栈中,最后是操作符“-”,所以再弹出d和c 进行d-c 运算,并将其结果再次放入栈中,此时表达式结束,则栈中的元素值就是该表达式最后的运算结果。当然将原始的中缀表达式转换为后缀表达式比较关键,要同时考虑操作符的优先级以及对有括号的情况下的处理,相关内容会在算法具体实现中详细讨论。 2、求值过程 一、将原始的中缀表达式中的操作数、操作符以及括号按顺序分解出来,并以字符串的 形式保存。 二、将分解的中缀表达式转换为后缀表达式的形式,即调整各项字符串的顺序,并将括 号处理掉。 三、计算后缀表达式的值。 3、中缀表达式分解 DivideExpressionToItem()函数。分解出原始中缀表达式中的操作数、操作符以及括号,保存在队列中,以本实验中的数据为例,分解完成后队列中的保存顺序如下图所示:</p><h2>表达式用二叉树表示(1)</h2><p>数据结构程序报告(3) 2011.3.29</p><p>2. 需求分析: (1)功能:表达式可以用二叉树表示,对于简单的四则运算,请实现以下功能【1】对于任意给出的前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号),能够在计算机内部构造出一棵表达式二叉树,并且图示出来(图形的形式)。 【2】对于构造好的内部表达式二叉树,按照用户的要求输出相应的前缀表达式(不带括号)、中缀表达式(可以带括号,但不允许冗余括)或后缀表达式(不带括号)。 提示:所谓中缀表达式中的冗余括号,就是去掉括号后不影响表达式的计算顺序。例如:“(c+b)+a”中的括号是冗余的,可以表示成不冗余的“c+b+a”。 (2)输入输出要求:请输入字符串表达式: 树形二叉树(图形显示) 中缀表达式为: 前缀表达式为: 后缀表达式为: 3.概要设计:(算法) 分成两部分完成: 【1】前缀、中缀、后缀表达式->二叉树表达式 前缀表达式->二叉树表达式:(a)碰到操作数则把其值赋给相应的新申请的二叉树结点,地址压栈;(b)碰到操作符则把其值赋给相应的新申请的二叉树,并从栈中弹出两个地址,分别作为其右指针和左指针,然后再把其地址压栈,最后一个地址即为二叉树的根结点地址。 中缀表达式->二叉树表达式:把中缀表达式转换成后缀表达式,然后再建立二</p><p>叉树。 后缀表达式->二叉树表达式:(a)碰到操作数则把其值赋给相应的新申请的二叉树结点,若栈为空则地址压栈,若非空则取栈顶元素,若栈顶元素的左孩子为空则当前结点设为其左孩子,左孩子为满则设为其右孩子再压栈;(b)碰到操作数则把其值赋给相应的新申请的二叉树结点,取栈顶元素,若栈顶元素的左孩子为空则设为其左孩子,左孩子为满则设为其右孩子开始那个元素地址为根结点地址,开始时用变量root保存。 【1】二叉树表达式->前缀、中缀、后缀表达式 二叉树表达式->前缀表达式:对二叉树表达式进行前序遍历。 二叉树表达式->中缀表达式:对二叉树表达式进行中序遍历,若结点操作符的优先级高于其左或右子树,在打印相应的子树之前先打印开括号,在打印相应的子树最后在打印一个闭括号。 二叉树表达式->后缀表达式:对二叉树表达式进行后序遍历。</p><h2>数据结构中二叉树各种题型详解及程序</h2><p>树是一种比较重要的数据结构,尤其是二叉树。二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。二叉树是递归定义的,因此,与二叉树有关的题目基本都可以用递归思想解决,当然有些题目非递归解法也应该掌握,如非递归遍历节点等等。本文努力对二叉树相关题目做一个较全的整理总结,希望对找工作的同学有所帮助。 二叉树节点定义如下: structBinaryTreeNode { intm_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; 相关链接: 轻松搞定面试中的链表题目 题目列表: 1. 求二叉树中的节点个数 2. 求二叉树的深度 3. 前序遍历,中序遍历,后序遍历 4.分层遍历二叉树(按层次从上往下,从左往右) 5. 将二叉查找树变为有序的双向链表 6. 求二叉树第K层的节点个数 7. 求二叉树中叶子节点的个数 8. 判断两棵二叉树是否结构相同 9. 判断二叉树是不是平衡二叉树 10. 求二叉树的镜像 11. 求二叉树中两个节点的最低公共祖先节点 12. 求二叉树中节点的最大距离 13. 由前序遍历序列和中序遍历序列重建二叉树 14.判断二叉树是不是完全二叉树 详细解答 1. 求二叉树中的节点个数 递归解法: (1)如果二叉树为空,节点个数为0 (2)如果二叉树不为空,二叉树节点个数= 左子树节点个数+ 右子树节点个数+ 1 参考代码如下: 1.int GetNodeNum(BinaryTreeNode * pRoot) 2.{ 3.if(pRoot == NULL) // 递归出口 4.return 0; 5.return GetNodeNum(pRoot->m_pLeft) + GetNodeNum(pRoot->m_pRight) + 1; 6.}</p><h2>C语言二叉树运算</h2><p>#include<stdio.h> #include<stdlib.h> typedef struct bitnode { char data; struct bitnode *lchild; struct bitnode *rchild; }bitnode,*bitree; bitree createbitree(bitree &T){ char ch; printf("输入结点值ch="); scanf("%c",&ch); scanf("%c",&ch); if(ch!='#'){ if(!(T=(bitnode*)malloc(sizeof(bitnode)))) return 0; T->data=ch; T->lchild=NULL; T->rchild=NULL; createbitree(T->lchild); createbitree(T->rchild); } return T; } void preorder(bitree &p) { if(p) { printf("%c",p->data); if(p->lchild!=NULL) preorder(p->lchild); if(p->rchild!=NULL) preorder(p->rchild); }else printf("NULL"); } void inorder(bitree &p) { if(p) {</p><p>if(p->lchild!=NULL) inorder(p->lchild); printf("%c",p->data); if(p->rchild!=NULL) inorder(p->rchild); } } void postorder(bitree &p) { if(p) { if(p->lchild!=NULL) postorder(p->lchild); if(p->rchild!=NULL) postorder(p->rchild); printf("%c",p->data); } } int number(bitree &bt){ int n1,n2; if(!bt)return 0; if(!bt->lchild&&!bt->rchild) return 1; n1=number(bt->lchild); n2=number(bt->rchild); return(n1+n2+1); } int leafs(bitree &bt){ int n1,n2; if(!bt) return 0; if(!bt->lchild&&!bt->rchild) return 1; n1=leafs(bt->lchild); n2=leafs(bt->rchild); return n1+n2; } int height(bitree &bt){ int h1,h2; if(!bt) return 0;</p><h2>算术表达式与二叉树课程设计</h2><p>山西大学 课程设计任务书 设计题目算术表达式与二叉树 所属课程:数据结构 系别软件学院 专业软件工程 班级软工1408班 姓名霍志斌 指导教师李雪梅 设计任务下达日期 2015年 12 月15 日 设计时间2016年1月4日至 2016年1月8日</p><p>目录: 一、需求分析 二、概要设计 1、数据类型的声明: 2、表达式的抽象数据类型定义 3、整体设计 三、详细设计 1、二叉树的存储类型 2、顺序栈的存储类型 3、表达式的基本操作 4、主程序和其他伪码算法 5、函数的调用关系 四、设计和调试分析 五、测试 六、课程设计的心得和心得以及问题 一、需求分析【课程设计要求】 【问题的描述】 一个表达式和一棵二叉树之间,存在着自然的对应关系。写一个程序,实现基于二叉树表示的算术表达式Expression的操作。 【基本要求】 假设算术表达式Expression内可以含有变量(a-z),常量(0-9)和二元运算符(+,-,*,/,^(乘幂))。实现以下操作: (1)ReadExpr(E)――以字符序列的形式输入语法正确的前缀表达式并构造表达式E。 (2)WriteExpr(E)――用带括号的中缀表达式输出表达式E。</p><p>(3)Assign(V,c)――实现对变量V的赋值(V=c),变量的初值为0。 (4)Value(E)――对算术表达式E求值。 (5)CompoundExpr(p,E1,E2)――构造一个新的复合表达式(E1)p(E2)。【测试数据】 1)分别输入0;a;-91;+a*bc;+*5x2*8x;+++*3^*2^x2x6并输出。 2)每当输入一个表达式后,对其中的变量赋值,然后对表达式求值。 二、概要设计 1、数据类型的声明: 在这个课程设计中,采用了链表二叉树的存储结构,以及两个顺序栈的辅助存储结构 /*头文件以及存储结构*/ #include<stdio.h> #include<conio.h> #include<stdlib.h> #include<string.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW 0 typedef int Status; 2、表达式的抽象数据类型定义 ADT Expression{ 数据对象D:D是具有数值的常量C和没有数值的变量V; 数据关系:R={<(V或者C)P(V或者C)>|V,C∈D, <(V或者C)P(V或者C)>表示由运算符P结合起来的表达式E} 基本操作: Status Input_Expr(&string,flag) 操作结果:以字符序列的形式输入语法正确的前缀表达式,保存到字符串string; 参数flag表示输出的提示信息是什么,输入成功返回OK,否则,返回ERROR。 void judge_value(&E,&string,i) 初始条件:树E存在,表达式的前缀字符串string存在; 操作结果:判断字符string[i],如果是'0'-'9'常量之间,二叉树结点E存为整 型;否则,存为字符型。 Status ReadExpr(&E,&exprstring) 初始条件:表达式的前缀形式字符串exprstring存在; 操作结果:以正确的前缀表示式exprstring并构造表达式E,构造成功,返回OK, 否则返回ERROR。 Status Pri_Compare(c1,c2)</p><h2>数据结构—— 树和二叉树知识点归纳</h2><p>第6章树和二叉树 6.1 知识点概述 树(Tree)形结构是一种很重要的非线性结构,它反映了数据元素之间的层次关系和分支关系。在计算机科学中具有广泛的应用。 1、树的定义 树(Tree)是n(n≥0)个数据元素的有限集合。当n=0时,称这棵树为空树。在一棵非空树T中: (1)有一个特殊的数据元素称为树的根结点,根结点没有前驱结点。 (2)若n>1,除根结点之外的其余数据元素被分成m(m>0)个互不相交的集合T1,T2,…,Tm,其中每一个集合Ti(1≤i≤m)本身又是一棵树。树T1,T2,…,Tm称为这个根结点的子树。 2、树的基本存储结构 (1)双亲表示法 由于树中的每一个结点都有一个唯一确定的双亲结点,所以我们可用一组连续的 存储空间(即一维数组)存储树中的结点。每个结点有两个域:一个是data域,存放结点信息,另一个是parent域,用来存放双亲的位置(指针)。 (2)孩子表示法 将一个结点所有孩子链接成一个单链表形,而树中有若干个结点,故有若干个单 链表,每个单链表有一个表头结点,所有表头结点用一个数组来描述这种方法通常是把每个结点的孩子结点排列起来,构成一个单链表,称为孩子链表。 (3)双亲孩子表示法 双亲表示法是将双亲表示法和孩子表示法相结合的结果。其仍将各结点的孩子结点分别组成单链表,同时用一维数组顺序存储树中的各结点,数组元素除了包括结点本身的信息和该结点的孩子结点链表的头指针之外,还增设一个域,存储该结点双亲结点在数组中的序号。 (4)孩子兄弟表示法 这种表示法又称为树的二叉表示法,或者二叉链表表示法,即以二叉链表作为树的存储结构。链表中每个结点设有两个链域,分别指向该结点的第一个孩子结点和下一个兄弟(右兄弟)结点。 3、二叉树的定义 二叉树(Binary Tree)是个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点。 4、满二叉树 定义:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子结点都在同一层上,这样的一棵二叉树称作满二叉树。 5、完全二叉树 定义:一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。完全二叉树的特点是:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。 6、二叉树的性质</p><h2>表达式二叉树</h2><p>数据结构与算法实习报告第4次上机实习报告</p><p>2 数据结构与算法实习报告 诚信保证:我保证没有抄袭他人作业!问题部分 1.1 问题描述 【1】对于任意给出的前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号),能够在计算机内部构造出一棵表达式二叉树,并且图示出来(图形的形式)。 【2】对于构造好的内部表达式二叉树,按照用户的要求输出相应的前缀表达式(不带括号)、中缀表达式(可以带括号,但不允许冗余括)或后缀表达式(不带括号)。 (2)输入输出要求: 请输入表达式类型;请输入表达式类型,前缀表达式输入-1,中缀表达式输入0,后缀表达式输入1. 请输入字符串表达式: 树形二叉树(图形显示) 中缀表达式为: 前缀表达式为: 后缀表达式为: 1.2 问题分析 一、前缀、中缀、后缀表达式->二叉树表达式</p><p>数据结构实习报告前缀表达式->二叉树表达式:从后往前扫描 (a)碰到操作数则把其值赋给相应的新申请的二叉树结点,地址压栈; (b)碰到操作符则把其值赋给相应的新申请的二叉树,若栈非空,从栈中弹出一个地址,则栈顶指针所指结点设置成当前结点左孩子,若栈非空,再从栈中弹出一个地址,则栈顶指针所指结点设置成当前结点右孩子,操作完毕后把当前节点压栈,最后一个地址即为二叉树的根结点地址。 中缀表达式->二叉树表达式:把中缀表达式转换成后缀表达式,然后再建立二叉树。 后缀表达式->二叉树表达式:从前往后扫描 (a)碰到操作数则把其值赋给相应的新申请的二叉树结点,若栈为空则地址压栈, (b)碰到操作符则把其值赋给相应的新申请的二叉树结点,若当前元素的左孩子为空则设为其左孩子,左孩子为满则设为其右孩子,开始那个元素地址为根结点地址,开始时用变量root保存。 二、二叉树表达式->前缀、中缀、后缀表达式 二叉树表达式->前缀表达式:对二叉树表达式进行前序遍历。 二叉树表达式->中缀表达式:对二叉树表达式进行中序遍历,如果当前节点的左子树是运算符,且运算符优先级低于当前运算符,那么左边的表达式要先计算,需要加括号,否则直接输出左子树;如果当前节点的右子树是运算符,且运算符优先级不高于当前运算符,那么右边的表达式要先计算,需要加括号,狗则直接输出右子树。</p><h2>基于二叉树结构的表达式求值算法</h2><p>实验报告 课程名称: 程序设计与数据结构 指导老师: ljq 成绩: 实验名称:基于二叉树结构的表达式求值算法 实验类型: 上机 同组学生姓名: 一、实验目的和要求(必填) 三、代码缺陷及修正记录 五、讨论、心得 二、实验内容和代码(必填) 四、实验结果与分析(必填) 一、实验目的和要求 1. 掌握编程工具的使用 2. 掌握二叉树数据结构在计算机上的实现 3. 掌握通过计算机编程解决问题的基本方法 二、实验内容和代码 1.实验内容: ● 编程实现基于二叉树结构的表达式求值算法 ● 表达式包含加减乘除四则运算以及至少一层括弧运算 ● 首先将输入的原表达式转换成二叉树结构,然后采用二叉树的后序递归遍历 方法求得表达式的值 ● 将所有实验内容合并到一个工程,增加交互操作和循环处理(持续) 2.代码 1.头文件expnbitree .h</p><p>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include<stdio.h> #include<string.h> #include<stdlib.h> #define EXP_LEN 100 //定义表达式的最大长度 #define DATA_LEN 20 //定义每个操作数的最大长度 typedef struct BiTNode { int dflag; //标志域,值为1,data[]存放操作运算符;值为0,data[]存放操作数char data[DATA_LEN + 1]; //数据域,存放:操作运算符或操作数 struct BiTNode *lchild, *rchild; //分别指向结点的左、右子树 }BiTNode, *BiTree; //定义二叉树结点及二叉树类型指针 int CreateBiTree(BiTree &bt, char *p, int len); //创建二叉树,并用bt返回树的根地址,p为表达式的首地址,l为表达式的长度 int Calculate(BiTree bt, double &rst); //计算表达式的值,bt为据表达式创建的二叉树,用rst返回表达式的值 int PreOrderTraverse(BiTree bt);//先序遍历二叉树bt,输出先序遍历序列 int InOrderTraverse(BiTree bt); //中序遍历二叉树bt,输出中序遍历序列 int PostOrderTraverse(BiTree bt); //后序遍历二叉树bt,输出后序遍历序列 int DestroyBiTree(BiTree &bt); //销毁二叉树 //二叉树结构的表达式求解算法入口</p><h2>习题树和二叉树</h2><p>习题6树和二叉树 说明: 本文档中,凡红色字标出的题请提交纸质作业,只写题号和答案即可。 6.1 单项选择题 1. 2. A . 15 由于二叉树中每个结点的度最大为 2,所以二叉树是一种特殊的树,这种说法 A.正确 假定在一棵二叉树中, B . 16 C . 17 3. 按照二叉树的定义, A. 3 4. 按照二叉树的定义, A. 5 5. 6. 7. 8. B.错误 双分支结点数为15,单分支结点数为30个,则叶子结点数为 B 个。 D . 具有 B. 4 具有 B. 6 深度为5的二叉树至多有 A. 16 B. 32 47 3个结点的不同形状的二叉树有 _ C. 5 D. 6 3个不同数据结点的不同的二叉树有 C. 30 _C__个结点。 C. 31 D. 32 C 种。 C 种。 设高度为h 的二叉树上只有度为 0和度为 D. 10 2的结点,则此类二叉树中所包含的结点数至少为 B. 2h-1 C. 2h+1 m 个树叶,n 个结点,深度为h ,则__A__ B. h+m=2 n C. m=h-1 D. h+1 A. 2h 对一个满二叉树, A. n=h+m 任何一棵二叉树的叶结点在先序、中序和后序遍历序列中的相对次序 A.不发生改变 B.发生改变 如果某二叉树的前根次序遍历结果为 B. vwuts C. wuvts O D. n=2 h -1 A C.不能确定 D.以上都不对 stuwv ,中序遍历为uwtvs ,那么该二叉树的后序为 __C__。 D. wutsv 9. A. uwvts 10. 二叉树的前序遍历序列中,任意一个结点均处在其子女结点的前面,这种说法 正确 B.错误 11. 某二叉树的前序遍历结点访问顺序是 序遍历的结点访问顺序是 _D__。 A. bdgcefha B. gdbecfha 12. 在一非空二叉树的中序遍历序列中, A.只有右子树上的所有结点 C.只有左子树上的部分结点 abdgcefh ,中序遍历的结点访问顺序是 13. 如图6.1所示二叉树的中序遍历序列是 C. bdgaechf D. gdbehfca 根结点的右边 _A_。 B.只有右子树上的部分结点 D.只有左子树上的所有结点 B_。 C. dbaefcg D. defbagc 序遍 A. abcdgef 序列 B. dfebagc abdgcefh B. dgbaechf D. abcdefgh 为一棵二叉树上的两个结点, 前的条件是 B a 在b 的右方 a 是b 的祖先 a . C . 已知某二叉树的后序遍历序列是 B. deca b C. deab c D . a 是b 的子孙 dabec ,中序遍历序列是 D. cedba 16. A. acbe d 17.实现任意二叉树的后序遍历的非递归算法而不使用栈结构, 结构。 A.二叉链表 B.广义表存储结构 C.三叉链表 A. dgbaechf ,则其后 二叉树如图6.2所示,其中序遍历的 疋 D 。 B . a 在b 的左方 debac,它的前序遍历序列是 最佳方案是二叉树采用 D.顺序存储结构 C. 在中 C 存储</p><h2>15算术表达式与二叉树</h2><p>《数据结构与算法》课程设计任务书 题目:算术表达式与二叉树 学生姓名:学号: 班级: 题目类型:软件工程(R)指导教师: 一.题目简介 一个表达式和一棵二叉树之间,存在着自然的对应关系。本设计要求学生编程实现基于二叉树表示的算术表达式的操作。通过该题目的设计过程,可以加深理解树及二叉树的逻辑结构、存储结构以及递归算法设计的基本原理,掌握树及二叉树上基本运算的实现。进一步理解和熟练掌握课本中所学的各种数据结构,学会如何把学到的知识用于解决实际问题,培养学生的动手能力。 二.主要任务 第一部分:基本算法实现 1、线性结构基本算法实现(指导老师根据题目指定); 2、树型结构基本算法实现(指导老师根据题目指定); 3、图型结构基本算法实现(指导老师根据题目指定); 4、查找基本算法实现(指导老师根据题目指定); 5、排序基本算法实现(指导老师根据题目指定); 第二部分:指定题目的设计与实现 1、查阅文献资料,一般在3篇以上; 2、建立数据的逻辑结构和物理结构; 3、完成相应算法的设计; 4、完成测试工作;</p><p>5、撰写设计说明书; 6、做好答辩工作。 三.主要内容、功能及技术指标 假设算术表达式Expression内可以含有变量(a~z)、常量(0~9)和二元运算符(+,-,*,/,^(乘幂))。实现以下操作: (1)ReadExpre(E)—以字符序列的形式输入语法正确的前缀表达式并构造表达式E。 (2)WriteExpre(E)—用带括弧的中缀表达式输出表达式E。 (3)Assign(V,c)—实现对变量V的赋值(V=c),变量的初值为0。 (4)Value(E)—对算术表达式E求值。 (5)CompoundExpr(P,E1,E2)--构造一个新的复合表达式(E1)P(E2)(6)算法对于精心选择的典型、苛刻而带有刁难性的几组输入数据能够得出满足规格说明要求的结果;对算法实现过程中的异常情况能给出有效信息; (7)较高要求:实现图形化操作界面。 四.提交的成果 1. 设计说明书一份,内容包括: 1) 中文摘要100字;关键词3-5个; 2) 序言; 3)采用类c语言定义相关的数据类型 4)各模块的伪码算法 5)函数的调用关系图 6)调试分析 a、调试中遇到的问题及对问题的解决方法; b、算法的时间复杂度和空间复杂度。 7)测试结果 8)源程序(带注释)</p><h2>c语言实现一.二叉树操作 二.用栈实现算术表达式求值 课设报告</h2><p>目录 题目一.二叉树操作(1)二.算术表达式求 (1) 一、课程设计的目的 (1) 二、课程设计的内容和要求 (1) 三、题目一设计过程 (2) 四、题目二设计过程 (6) 五、设计总结 (17) 六、参考文献 (18)</p><p>题目一.二叉树操作(1)二.算术表达式求 一、课程设计的目的 本学期我们对《数据结构》这门课程进行了学习。这门课程是一门实践性非常强的课程,为了让大家更好地理解与运用所学知识,提高动手能力,我们进行了此次课程设计实习。这次课程设计不但要求学生掌握《数据结构》中的各方面知识,还要求学生具备一定的C语言基础和编程能力。 (1)题目一的目的: 1、掌握二叉树的概念和性质 2、掌握二叉树的存储结构 3、掌握二叉树的基本操作 (2)题目二的目的: 1、掌握栈的顺序存储结构和链式存储结构 2、掌握栈的先进后出的特点 3、掌握栈的基本运算 二、课程设计的内容和要求 (1)题目一的内容和要求: 1、编写已知二叉树的先序、中序序列,恢复此二叉树的程序 2、编写求二叉树深度的程序 (2)题目二的内容和要求: 1、算术表达式由操作数、运算符和界限符组成。操作数是正整数,运算符为 加减乘除,界限符有左右括号和表达式起始 2、将一个表达式的中缀形式转化为相应的后缀形式 3、依据后缀表达式计算表达式的值</p><p>三、题目一设计过程 1、题目分析 现已知一棵二叉树的先序遍历序列和中序遍历序列,依次从先序遍历序列中取结点,由先序序列确定根结点(就是第一个字母),每次取出一个结点就与中序遍历的序列进行比较,当相等的时候,中序遍历序列就被分成以该结点为根的二叉树子树,该结点左部分为左子树,右部分为右子树,直到取完先序列里的所有结点,则二叉树构造完毕(树用链式存储结构存储),用递归实现! 由建好的二叉树,先判断这棵树是否为空,若不为空则找数的左子树,统计它的高度,然后找树的右子树,统计它的高度,比较左子树和右子树的高度,然后返回其中大的那个值加一,则求出数的高度。这里用递归实现! 2、算法描述 main ( )(主函数) 先构造一颗二叉树,初始化为空,用来存储所构造的二叉树,并输入一棵树的先序序列和中序序列,并统计这个序列的长度。然后调用实现功能的函数。 void CreateBiTree(BiTree *T,char *pre,char *in,int len)(由先序序列和中序序列构造二叉树) 根据前序遍历的特点, 知前序序列(pre)的首个元素(pre[0])为根(root), 然后在中序序列(in)中查找此根(pre[0]), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为左子树, 后边的序列为右子树。设根前边有n个元素,则又有, 在前序序列中,紧跟着根(root)的n个元素序列(即pre[1...n]) 为左子树, 在后边的为右子树,而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为pre[1...n]), 中序序列为in[0...n-1], 分别为原序列的子串, 构造右子树同样。这里用递归实现! int Depth(BiTree T)(求树的深度) 当所给的参数T是NULL时,返回0。说明这个树只有一个叶子节点深度为0,当所给的参数不是NULL时,函数调用自己看看这个参数的左分支是不是NULL,</p></div> <div class="rtopicdocs"> <div class="coltitle">相关主题</div> <div class="relatedtopic"> <div id="tabs-section" class="tabs"> <ul class="tab-head"> <li id="17043120"><a href="/topic/17043120/" target="_blank">二叉树求表达式的值</a></li> <li id="8190706"><a href="/topic/8190706/" target="_blank">表达式用二叉树表示</a></li> <li id="1796158"><a href="/topic/1796158/" target="_blank">二叉树结点</a></li> </ul> </div> </div> </div> </div> <div id="rightcol" class="viewcol"> <div class="coltitle">相关文档</div> <ul class="lista"> <li><a href="/doc/3617956429.html" target="_blank">表达式用二叉树表示</a></li> <li><a href="/doc/8b2768419.html" target="_blank">二叉树的前中后序遍历以及表达式树</a></li> <li><a href="/doc/a56628687.html" target="_blank">简易计算器(二叉树)</a></li> <li><a href="/doc/1310556397.html" target="_blank">算术表达式与二叉树</a></li> <li><a href="/doc/367755054.html" target="_blank">实验二叉树及其应用(严选材料)</a></li> <li><a href="/doc/5e13715807.html" target="_blank">二叉树表达式求值</a></li> <li><a href="/doc/9512102299.html" target="_blank">算术表达式(例题)-二叉树</a></li> <li><a href="/doc/d211948621.html" target="_blank">严蔚敏《数据结构(c语言版)习题集》答案第六章 树和二叉树文库</a></li> <li><a href="/doc/2e13247771.html" target="_blank">C语言二叉树运算</a></li> <li><a href="/doc/3f14385832.html" target="_blank">四则运算表达式求值(栈+二叉树,c++版)</a></li> <li><a href="/doc/7f17666466.html" target="_blank">后序遍历二叉树实现表达式求值</a></li> <li><a href="/doc/aa2847383.html" target="_blank">二叉树求表达式的值</a></li> <li><a href="/doc/089185739.html" target="_blank">波兰算法求二叉树表达式的值</a></li> <li><a href="/doc/3d3094389.html" target="_blank">c语言实现一.二叉树操作 二.用栈实现算术表达式求值 课设报告</a></li> <li><a href="/doc/594264392.html" target="_blank">四则运算表达式求值(栈+二叉树,c++版)(内容清晰)</a></li> <li><a href="/doc/948319417.html" target="_blank">表达式二叉树</a></li> <li><a href="/doc/c73047344.html" target="_blank">C语言实现一.二叉树操作 二.用栈实现算术表达式求值 课设报告</a></li> <li><a href="/doc/1016818517.html" target="_blank">表达式用二叉树表示(1)</a></li> <li><a href="/doc/3212743551.html" target="_blank">15算术表达式与二叉树</a></li> <li><a href="/doc/7016191991.html" target="_blank">第6章 树和二叉树习题</a></li> </ul> <div class="coltitle">最新文档</div> <ul class="lista"> <li><a href="/doc/0f19509601.html" target="_blank">幼儿园小班科学《小动物过冬》PPT课件教案</a></li> <li><a href="/doc/0119509602.html" target="_blank">2021年春新青岛版(五四制)科学四年级下册 20.《露和霜》教学课件</a></li> <li><a href="/doc/9b19184372.html" target="_blank">自然教育课件</a></li> <li><a href="/doc/3019258759.html" target="_blank">小学语文优质课火烧云教材分析及课件</a></li> <li><a href="/doc/d819211938.html" target="_blank">(超详)高中语文知识点归纳汇总</a></li> <li><a href="/doc/a419240639.html" target="_blank">高中语文基础知识点总结(5篇)</a></li> <li><a href="/doc/9d19184371.html" target="_blank">高中语文基础知识点总结(最新)</a></li> <li><a href="/doc/8a19195909.html" target="_blank">高中语文知识点整理总结</a></li> <li><a href="/doc/8519195910.html" target="_blank">高中语文知识点归纳</a></li> <li><a href="/doc/7f19336998.html" target="_blank">高中语文基础知识点总结大全</a></li> <li><a href="/doc/7119336999.html" target="_blank">超详细的高中语文知识点归纳</a></li> <li><a href="/doc/6619035160.html" target="_blank">高考语文知识点总结高中</a></li> <li><a href="/doc/6719035161.html" target="_blank">高中语文知识点总结归纳</a></li> <li><a href="/doc/4a19232289.html" target="_blank">高中语文知识点整理总结</a></li> <li><a href="/doc/3b19258758.html" target="_blank">高中语文知识点归纳</a></li> <li><a href="/doc/2619396978.html" target="_blank">高中语文知识点归纳(大全)</a></li> <li><a href="/doc/2b19396979.html" target="_blank">高中语文知识点总结归纳(汇总8篇)</a></li> <li><a href="/doc/1419338136.html" target="_blank">高中语文基础知识点整理</a></li> <li><a href="/doc/ed19066069.html" target="_blank">化工厂应急预案</a></li> <li><a href="/doc/bd19159069.html" target="_blank">化工消防应急预案(精选8篇)</a></li> </ul> </div> </div> <script> var sdocid = "7afdd748c081e53a580216fc700abb68a882ad53"; </script> <div class="clearfloat"></div> <div id="footer"> <div class="ft_info"> <a href="https://beian.miit.gov.cn">闽ICP备16038512号-3</a>&nbsp;<a href="/tousu.html" target="_blank">侵权投诉</a> &nbsp;&copy;2013-2023 360文档中心,www.360docs.net | <a target="_blank" href="/sitemap.html">站点地图</a><br /> 本站资源均为网友上传分享,本站仅负责收集和整理,有任何问题请在对应网页下方投诉通道反馈 </div> <script type="text/javascript">foot()</script> </div> </body> </html>