[Algorithm] Given an array posArr that is traversed after searching for a binary tree, reconstruct the tree according to posArr

It is known that an array posArr is traversed after searching for a binary tree, and the tree is reconstructed according to posArr

/**
 * 已知一个搜索二叉树后序遍历的数组,建对应树并返回头结点
 *
 *      8
 *     / \
 *    4   10
 *   / \  / \
 *  2  6 9  12
 *
 *  后续遍历结果:[2,6,4,9,12,10,8]
 *
 *
 *  思路:
 *  1.后序遍历的最后一个数绝对是根节点
 *  2.找左子数:从[left,right-1]范围开始找比最后一个数字小的数的最右面的那个数,记录该数字的下标为M
 *    比如这里的arr[M] = 4
 *  3.找右子树:从[M+1,right-1]范围找比根节点大的最后一个数,实际上就是arr[right-1]
 *  4.继续递归进行
 */
public class MyPostTree {
    
    
    public static void main(String[] args) {
    
    
        //打印搜索二叉树
        int[] arr = {
    
    2,6,4,9,12,10,8};
        printTree(posArrayToBST(arr));

    }

    static class Node{
    
    
        private int val;
        private Node left;
        private Node right;
        public Node(int val){
    
    
            this.val = val;
        }
    }

    /**
     * 构建树,O(N^2)
     * @param arr
     * @param left
     * @param right
     * @return
     */
    public static Node postTree(int[] arr,int left,int right){
    
    
        if (left > right){
    
    
            return null;
        }
        Node node = new Node(arr[right]);
        if (left == right){
    
    
            return node;
        }
        //处理极端情况
        int m = left - 1;
        for (int i = left;i<right;i++){
    
    
            if (arr[i] < arr[right]){
    
    
                m = i;
            }
        }
        // 情况一:如果只有左子树,比如 arr[1,2,3,4,5,6],即都是比最后一个数小
        // node.right分支就会出现 left > right场景,即传入的是(arr,right,right-1),正好使得右节点为null;
        //
        // 情况二:如果只有右子树,比如 arr[6,5,4,3,2,1],即都是比最后一个数大
        // 此时 m =left-1, head.left分支就会出现 left > right场景,所以 m 赋值为left-1恰到好处;
        node.left = postTree(arr,left,m);
        node.right = postTree(arr,m+1,right-1);
        return node;
    }

    /**
     * 优化构建树:不使用遍历查找m,使用二分查找 O(N*log2N)
     * @param arr
     * @param left
     * @param right
     * @return
     */
    public static Node postTreeV2(int[] arr,int left,int right){
    
    
        if (left > right){
    
    
            return null;
        }
        Node node = new Node(arr[right]);
        if (left == right){
    
    
            return node;
        }
        //处理极端情况
        int m = left - 1;
        int L = left;
        int R = right-1;
       while (L <= R){
    
    
           int mid = L + ((R - L) >> 1);
           if (arr[mid] < arr[right]){
    
    
                m = mid;
                //mid 左侧不要,右侧继续二分
                L = mid + 1;
           }else{
    
    
               //mid 右侧不要,左侧二分继续
                R = mid - 1;
           }
       }
        node.left = postTree(arr,left,m);
        node.right = postTree(arr,m+1,right-1);
        return node;
    }


    //**********************************************************************

    //构建搜索二叉树
    public static Node posArrayToBST(int[] posArr) {
    
    
        if (posArr == null) {
    
    
            return null;
        }
        return postTree(posArr, 0, posArr.length - 1);
        //postTreeV2(posArr, 0, posArr.length - 1)
    }
    // 先序遍历打印二叉树
    public static void printTree(Node head) {
    
    
        System.out.println("Binary Tree:");
        printInOrder(head, 0, "H", 17);
        System.out.println();
    }

    public static void printInOrder(Node head, int height, String to, int len)
    {
    
    
        if (head == null) {
    
    
            return;
        }
        printInOrder(head.right, height + 1, "v", len);
        String val = to + head.val + to;
        int lenM = val.length();
        int lenL = (len - lenM) / 2;
        int lenR = len - lenM - lenL;
        val = getSpace(lenL) + val + getSpace(lenR);
        System.out.println(getSpace(height * len) + val);
        printInOrder(head.left, height + 1, "^", len);
    }

    public static String getSpace(int num) {
    
    
        String space = " ";
        StringBuffer buf = new StringBuffer("");
        for (int i = 0; i < num; i++) {
    
    
            buf.append(space);
        }
        return buf.toString();
    }
}

operation result:
Insert picture description here

Guess you like

Origin blog.csdn.net/i_nclude/article/details/112210726