二叉树的应用——表达式树的原理分析与实现(Java语言)
2017-12-03 17:16
519 查看
表达式树
表达式树(expression tree)的树叶是操作数(operand),如常量或变量名,而其他节点为操作符(operator)。如下图图1 (a+b*c)+((d*e+f)*g)的表达式树
我们可以通过递归地产生一个带括号的左表达式,然后打印出在跟出的运算符,最后再递归地产生一个带括号的右表达式从而得到一个中缀表达式。这种一般的方法(左,节点,右)的方式成为中序遍历。
构造表达式树
我们现在给出一个算法来把后缀表达式转变成表达式树。设输入为:
a b + c d e + * *
前两个符号是操作数,因此创建两颗单节点书并将它们压入栈中。
接着,+被读取,因此两棵树被弹出,一颗新的树形成,并被压入栈中。
然后,c、d、e被读入,分别创建对应的单节点树,然后压入栈中。
接下来读到+号,因此两棵树合并。
继续进行,读到*号,弹出两棵树合成一颗新的树并压入栈中。
最后,读入最后一个符号,两棵树合并,而最后的树被留在栈中。
从后缀表达式构造表达式树的实现
创建节点类BinaryNode.classpublic class BinaryNode { String element; BinaryNode left; BinaryNode right; public BinaryNode(String element) { this.element = element; } public BinaryNode(String element, BinaryNode left, BinaryNode right) { this.element = element; this.left = left; this.right = right; } //为节省篇幅,getter()、setter()方法略去,请自行补充 }
常见一个ExpressionTree.class类,该类有三个静态方法,分别是:postfixToExpressionTree(String[] expressions)、printBinaryTree(int depth,BinaryNode binaryNode)和main(String[] args)。
postfixToExpressionTree(String[] expressions)方法负责将后缀表达式构造成表达式树并返回:
/** * 构造表达式树的静态方法。 * 遍历表达式,若为操作数则构造单节点树压入stack,若为操作符,则弹出两个节点,与 * 操作符构造成新的树,再压入stack中。最后stack中只剩一个节点,该节点就是我们要求的 * 表达式树。 * @param expressions 后缀表达式分解过后的字符串数组 * @return 表达式树 */ public static BinaryNode postfixToExpressionTree(String[] expressions){ BinaryNode operand1; //用于暂存弹出的BinaryNode节点 BinaryNode operand2; Stack<BinaryNode> stack = new Stack<BinaryNode>(); //用于构造表达式树的栈 for (String s:expressions) { //遍历表达式 if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")){ operand1=stack.pop(); //弹出操作数 operand2=stack.pop(); stack.push(new BinaryNode(s,operand2,operand1)); //构造成新树并压入栈中 }else { stack.push(new BinaryNode(s)); } } return stack.pop(); }
printBinaryTree(int depth,BinaryNode binaryNode)方法负责打印二叉树,并在每个节点前锁紧与深度相当的空格,方便观察树的结构。
/** * 打印二叉树的方法。 * 通过递归调用来打印二叉树。并在节点前缩进了与深度相当的空格,方便观察。 * @param depth 当前节点在树中的的深度 * @param binaryNode 当前树节点 */ public static void printBinaryTree(int depth,BinaryNode binaryNode){ for (int i=0;i<depth;i++){ //打印与深度相当的缩进 System.out.print(" "); } System.out.println(binaryNode.getElement()); //打印当前节点的数据 if (binaryNode.getLeft() != null){ //若左子树不为空,那么递归调用打印方法,打印左子树 printBinaryTree(depth+1,binaryNode.getLeft()); } if (binaryNode.getRight() != null){ //若右子树不为空,那么递归调用打印方法,打印右子树 printBinaryTree(depth+1,binaryNode.getRight()); } }
main()方法用于测试,负责接收表达式并将其拆解成字符串数组,传递给postfixToExpressionTree方法,然后调用printBinaryTree方法打印返回的表达式树。
/** * 测试构造和打印表达式树的方法。 * main()方法用于测试,负责接收表达式并将其拆解成字符串数组,传递给 * postfixToExpressionTree方法,然后调用printBinaryTree方法打印返回的表达式树。 * @param args 忽略 */ public static void main(String[] args) { Scanner in = new Scanner(System.in); String s = in.nextLine(); //接收表达式 String[] splits= s.split(""); //分解成字符串数组 BinaryNode binaryNode=postfixToExpressionTree(splits); //构造比表达式树 printBinaryTree(0,binaryNode); //打印表达式树 }
运行测试,输入ab+cde+**,输出结果为:
* + a b * c + d e
完整的实例已经分享到Github,项目地址:https://github.com/Dodozhou/Algorithm
相关文章推荐
- Java 8 动态类型语言Lambda表达式实现原理分析
- Java 8 动态类型语言Lambda表达式实现原理分析
- JAVA语言实现二叉树的层次遍历的非递归算法及递归算法。
- Java NIO原理 图文分析及代码实现
- Java NIO原理 图文分析及代码实现
- java语言实现的二叉树的各种操作(包括递归与非递归遍历二叉树,求二叉树的高度,节点总数,叶子节点等)
- 深入分析基于VCL派生的ActiveX控件的实现原理及应用
- 编译原理实习(应用预测分析法LL(1)实现语法分析)
- [转]Java NIO原理图文分析及代码实现
- java比较器的应用(实现二叉树的排序算法)
- Java NIO原理图文分析及代码实现
- 微信应用--天气预报的实现 java语言
- Java 虚拟机类装载:原理、实现与应用
- Java NIO原理图文分析及代码实现<转>
- Java NIO原理 图文分析及代码实现
- JAVA语言实现二叉树的层次遍历的非递归算法及递归算法
- 一个小语言的词法分析程序原理及其实现(2)
- 利用JAVA的动态属性之反射原理实现一个简单AOP容器 - AOP的实现原理分析
- Java对象池技术的原理及其实现 --Java对象的生命周期分析
- Java NIO原理 图文分析及代码实现