zoukankan      html  css  js  c++  java
  • 表达树—构建表达式树、获取表达式(二)

    回顾二叉树的递归遍历

    •   前序遍历:访问根结点-->前序遍历根结点的左子树-->前序遍历根结点的右子树。
    •   中序遍历:中序遍历根结点的左子树-->访问根结点-->中序遍历根结点的右子树。
    •   后序遍历:后序遍历根结点的左子树-->后序遍历根结点的右子树-->访问根结点。

    二叉树递归遍历获得表达式

      假设,已知中缀表达式为:(A+B*C)/D,需要获得前缀表达式,后缀表达式。

      

      总结:表达树的前序遍历为前缀表达式,中序遍历为中缀表达式,后续遍历为后缀表达式。

    •   前缀表达式(前序遍历):/+A*CBD。
    •   中缀表达式(中序遍历):A+B*C/D。
    •     后缀表达式(后序遍历):ACB*+D/。

    利用后缀表达式构建表达式树

      后缀表达式:ACB*+D/。

      算法思想:

    1. 依次读取字符。
    2. 如果该符号是操作数,创建操作数结点并且入栈。
    3. 如果该符号为操作符,把栈顶T1、T2相继出栈,创建操作符结点,操作符结点的左右孩子分别为T1、T2,最后把操作符结点入栈。

    Java代码实现构建过程

      二叉链表结构

    //二叉树节点
    public class BinaryTreeNode {
        private int data;
        private BinaryTreeNode left;
        private BinaryTreeNode right;
    

    }

       算法实现

    public class ExprTree {
        //最后访问头结点
        public BinaryTreeNode buildExprTree(char postfixExpr[],int size){
            LinkedList<BinaryTreeNode> stack=new LinkedList();
            BinaryTreeNode node=null;
            for(int i=0;i<size;i++){
                if(isOperateNum(postfixExpr[i])){
                    node=new BinaryTreeNode();
                    node.setLeft(null);
                    node.setRight(null);
                    node.setData(postfixExpr[i]);
                    stack.push(node);
                }else{
                    BinaryTreeNode leftChild=stack.pop();
                    BinaryTreeNode rightChild=stack.pop();
                    node =new BinaryTreeNode();
                    node.setLeft(leftChild);
                    node.setRight(rightChild);
                    node.setData(postfixExpr[i]);
                    stack.push(node);
                }
            }
            return stack.getLast(); 
        }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">判断是否是操作数</span>
    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">boolean</span> isOperateNum(<span style="color: #0000ff;">char</span><span style="color: #000000;"> c){
        </span><span style="color: #0000ff;">if</span>(c=='/'||c=='+'||c=='*'||c=='-'<span style="color: #000000;">){
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;
        }
        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
    }
    

    }

     发散思考-更进一步

    1. 我们肯定会思考,为什么选用后缀表达式构建?而不选择前缀表达式、后缀表达式呢?源于各表达式结构,采用后缀表达式更容易实现构建。
    2. 如果已知前缀表达式、中缀表达式,怎么办呢?曲线救国,先把前缀表达式、中缀表达式转换成后缀表达式去构建,否则只能利用栈的相关算法实现。
    3. 总结:所有的解决方案没有独步天下,只有适合某一个场景下。若碰见前缀表达式,求其他中缀、后缀,那就用栈的算法实现吧。
    4. 利用栈转换表达式参考:http://www.cnblogs.com/qiuyong/p/6790290.html
  • 相关阅读:
    随机抢红包算法实现
    C#Random函数在循环中每次获取一样的值
    YouTube Cobalt 浏览器支持
    原生js,通过document.getElementByClassName获取元素的索引值
    http请求415错误Unsupported Media Type
    axios
    vue项目中,localhost可以访问,IP无法访问的问题
    时间戳
    Vue.Draggable:基于 Sortable.js 的 Vue 拖拽组件使用中遇到的问题
    empty 与 remove 的区别
  • 原文地址:https://www.cnblogs.com/qiuyong/p/6791720.html
Copyright © 2011-2022 走看看