表达树—构建表达式树、获取表达式(二)

回顾二叉树的递归遍历

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

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

  假设,已知中缀表达式为:(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
posted @ 2017-05-01 13:05  码农皮邱  阅读(4697)  评论(0编辑  收藏  举报