重建二叉树.2

Q:根据前序遍历和后续遍历序列可以唯一确定一颗二叉树吗?
A:先序遍历和后序遍历为什么不能唯一地确定一棵树?
结论是:如果树中所有结点的度为0或者2,则可以唯一还原。
当一个结点只有一个子结点(非空)时,则不能唯一还原。

static class Node
    {
        public int data;
        public Node left;
        public Node right;
    }
    public static Node create(int[] preArr,int[] postArr)
    {
        if (preArr==null||postArr==null||preArr.length==0||postArr.length==0)
        {
            return null;
        }
        return createHelper(preArr,0,preArr.length-1,postArr,0,postArr.length-1);
    }
    public static Node 
        createHelper(int[] preArr,int preStart,int preEnd,int[] postArr,int postStart,int postEnd)
    {
        if (preArr[preStart]!=postArr[postEnd])
        {
            throw new RuntimeException("Invalid input");
        }
        Node root=new Node();
        //根节点就是前序遍历中开头的节点
        root.data=preArr[preStart];
        if (preStart==preEnd)
        {
            if (postStart==postEnd)
            {
                return root;
            }
            else
            {
                throw new RuntimeException("input valid");
            }
        }
        //说明根节点度为1,只有一个孩子节点,这时无法唯一确定这颗二叉树
        if (preArr[preStart+1]==postArr[postEnd-1])
        {
            throw new RuntimeException("Can't determine the tree");
        }
        //例如前序为:ABDECFG,后序为DEBFGCA
        //A肯定是根节点,然后B是左孩子节点,C是右孩子节点
        //先找到C在前序遍历序列中的位置:A BDE CFG
        //则BDE就是A的左子树,CFG就是A的右子树
        //同样在后序遍历序列中:DEB FGC A
        //则DEB就是A的左子树,FGC就是A的右子树
        //*********************************************************
        //找到前序遍历序列中右子结点的位置
        int temp=preStart;
        while (temp<=preEnd&&preArr[temp]!=postArr[postEnd-1])
        {
            temp++;
        }
        if (temp>preEnd)
        {
            throw new RuntimeException("input valid");
        }
        int leftLen=temp-preStart-1;
        if (leftLen>0)
        {
            root.left=createHelper(preArr,preStart+1,temp-1,postArr,postStart,postStart+leftLen-1);
        }
        if (leftLen

你可能感兴趣的:(重建二叉树.2)