大学学习数据结构的时候做过一个计算算术表达式字符串结果的小程序,最近学习java接触到了类似的问题,不过不是计算结果,而是利用它来构造二叉树,难度稍微大了一些。我在这里提供两种解决方案。相信很多人都知道怎么计算表达式的值,利用两个栈(符号栈和数字栈)根据运算符优先级进行出栈入栈操作,我们知道将栈中的运算符和数字替换为二叉树的节点就可以在这个过程中顺利的构造一个二叉树出来。第二种方法利用了递归的思想,我们构造二叉树的难点其实主要在于括号的存在,假设一个没有括号的算数表达式,如1+2*3-8/4,我们取得第一个运算符+的时候,将其作为一个树节点,将1和2分别作为左孩子和右孩子;当我们取得*时,将2和3分别作为它的左右孩子,由于*优先于+,所以*将成为+的右孩子;当我们取得-时,将3和8作为其左右孩子,由于-优先级低于*,所以要往上找*的父亲+,由于-的优先级低于+,所以继续找+的父亲,由于+已经没有父亲,+将成为-的孩子;最后取得/时,由于/优先级高于-,所以直接作为-的右孩子。个人感觉这两种方法都比较好理解。第二种方法的二叉树构造顺序如下(直线上的数字代表构造的次序,比较有趣的是用第一种方法和第二种方法构造出来的二叉树好像是一样的):
其中用到了基本的数据结构树节点TreeNode<E>,使用时应该用TreeNode<Character>,特别注意第一种方法不要求树节点中保存父指针,但第二种要求要保留父指针。两种方法的核心代码列在下面了:
第一种:
/** * 将part解析为二叉树 * @param part * @return 返回二叉树的根节点,解析失败返回null */ public TreeNode<Character> createBinaryTree(String part){ //定义数字栈和操作符栈 Stack<TreeNode<Character>> numStack=new Stack<TreeNode<Character>>(); Stack<TreeNode<Character>> operStack=new Stack<TreeNode<Character>>(); operStack.push(new TreeNode<Character>('#',null,null,null)); for(int i=0;i<part.length();i++){ //是数字则直接压入数字栈 if(isNumber(part.charAt(i))){ numStack.push(new TreeNode<Character>(part.charAt(i),null, null,null)); continue; } //是操作符(注意这里没有把左右括号当做操作符)或者左括号,则尝试压入 //符号栈 if(isOperator(part.charAt(i))||part.charAt(i)=='('){ Character top=operStack.get(operStack.size()-1).getData(); //如果准备压入的符号比栈顶端的符号优先级低,则栈顶段的符号 //和数字栈中的数字应该弹出,两个数字是符号节点的左右孩子, //再将符号节点压入数字栈(此时该符号节点已经代表一个数字了, //所以要压入数字栈) while(getPriority(top, part.charAt(i))<0){ //如果符号栈只剩下#,说明算术表达式已经解析完了,返 //回数字栈中的节点 if(top=='#'){ return numStack.pop(); } TreeNode<Character> temp=operStack.pop(); TreeNode<Character> right=numStack.pop(); TreeNode<Character> left=numStack.pop(); temp.setLefChild(left); temp.setRigChild(right); numStack.push(temp); top=operStack.get(operStack.size()-1).getData(); } operStack.push(new TreeNode<Character>(part.charAt(i),null,null,null)); continue; } //如果将入栈的是右括号,则符号栈弹出符号并和数字栈弹出的数字组建树节 //点,知道碰到左括号。 if(part.charAt(i)==')'){ Character top=operStack.get(operStack.size()-1).getData(); while(top!='('){ TreeNode<Character> temp=operStack.pop(); TreeNode<Character> right=numStack.pop(); TreeNode<Character> left=numStack.pop(); temp.setLefChild(left); temp.setRigChild(right); numStack.push(temp); top=operStack.get(operStack.size()-1).getData(); } operStack.pop(); continue; } } return null; } 第二种方法:
/** * 利用算数字符串content构造二叉树binaryTree */ public TreeNode<Character> CreateBinaryTree(String part){ //先将表达式转换为由不含括号的节点组成的链表结构 List<TreeNode<Character>> list=new ArrayList<TreeNode<Character>>(); for(int i=0;i<part.length();i++){ if(isNumber(part.charAt(i)) || isOperator(part.charAt(i))){ list.add(new TreeNode<Character>(part.charAt(i),null,null, null)); }else { //如果不是操作数和操作符,那肯定是括号,如果表达式正确, //第一碰到的括号肯定是左括号 int right=findFitBracket(part, i); String subPart=new String(part.substring(i+1, right)); list.add(CreateBinaryTree(subPart)); i=right; } } //根据这个不含括号的链表结构构造二叉树 TreeNode<Character> cur=null; for(int i=0;i<list.size();i++){ if(isOperator(list.get(i).getData()) && list.get(i).getLefChild() ==null){ list.get(i).setLefChild(list.get(i-1)); list.get(i).setRigChild(list.get(i+1)); list.get(i-1).setFather(list.get(i)); list.get(i+1).setFather(list.get(i)); if(cur==null) cur=list.get(i); else { while(priority(cur.getData(),list.get(i).getData())<0 && cur.getFather()!=null) cur=cur.getFather(); if(cur.getFather()==null && priority(cur.getData(), list.get(i).getData())<0){ list.get(i).setLefChild(cur); cur.setFather(list.get(i)); } else { if(priority(cur.getData(), list.get(i).getData())>0){ cur.setRigChild(list.get(i)); list.get(i).setFather(cur); } } } cur=list.get(i); } } while(cur.getFather()!=null) cur=cur.getFather(); return cur; }
相关推荐
这是数据结构课程设计,二叉树表示的算术表达式
我需要写一个程序,实现基于二叉树表示的算术表达式的操作。 1.2这个算法的要求 假设算术表达式Expression内可以含有变量(a~z)、常量(0~9)和二元运算符(+,,*,/, ^(乘幂)。实现以下操作: (1) ReadExpre(E)- _以...
众所周知是数据结构的课程设计------------------题目要求:一个表达式和一棵二叉树之间,存在着自然的对应关系。写一个程序,实现基于 二叉树表示的算术表达式的操作。
Java版的源码,可应用于数据结构的课程设计,非常完美的源码
完整的课程设计报告!!! 有32页哦! 数据结构课程设计,二叉树表示的算术表达式
(4) Value(E)-对算术表达式 E 求值。 (5) CompoundExpr (P, E1,E2) -_构造-一个新的复合表达式(E1) P (E2) [测试数据] (1)分别输入 0; a; -91; +a*bc; +*5^x2*8x; +++*3^x3*2^x2x6 并输出。 (2)每当输入一个...
数据结构的课程设计,输入字符串的算术表达式,以二叉树的形式存储算术表达式,计算表达式结果并输出
算术表达式求值,遍历二叉树,中序前序,后序
1、算术表达式由操作数、运算符和界限符组成。操作数是正整数,运算符为加减乘除,界限符有左右括号和表达式起始 2、将一个表达式的中缀形式转化为相应的后缀形式 3、依据后缀表达式计算表达式的值
题目:设计一个程序实现基于二叉树表示的算术表达式的操作。
由键盘输入一算术表达式,以中缀形式输入,试编写程序将中缀表达式转换成一棵二叉表达式树,通过对该的后序遍历求出计算表达式的值。 基本要求: a.要求对输入的表达式能判断出是否合法。不合法要有错误提示信息...
输入一个前缀或后缀表达式 输出一个相应二叉树
详细介绍了“二叉树与算术表达式的应用”数据结构课程设计流程;提供了c语言源代码;
根据逆波兰表达式将各序表达式显示出来,并且将二叉树输出
将中缀表达式转换为二叉树、后序遍历二叉树转为后缀表达式、计算后缀表达式
输入一表达式,将其用表达式树表示,并用表达式数计算表达式的值。
中缀后缀表达式变表达式二叉树并且三种顺序历遍.zip
用二叉树实现中缀表达式转换成后缀表达式,内含一个CPP文件的代码和一个截图,很不错的,是我自己写的。
表达式求值,用二叉树来表示以后,进行遍历求解。
选择输入前中后缀表达式,建立表达式二叉树,再前序中序后序遍历二叉树,输出三种形式的表达式