前序中序后序重建二叉树

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1169091731/article/details/85316443

前序+中序:


    public TreeNode buildTree(int[] preorder, int[] inorder) {

        return buildTree(preorder, inorder, 0, 0, inorder.length);
    }

    public TreeNode buildTree(int[] pre, int[] in, int preStart, int inStart, int length) {

        if (length == 0) return null;

        // inStart==inEnd 也要进行下面的步骤,防止pre 和 in 序列不匹配

        //  构造以 pre[preStart] 为根节点的树
        int j = 0; // 中序中找到根节点
        while (j < length && in[j + inStart] != pre[preStart]) {
            j++;
        }
        if (j >= length) {
            throw new RuntimeException("前序中序不匹配");
        }
        TreeNode root = new TreeNode(pre[preStart]);

        // 左子树的节点数 j , 右子树的节点数 length-j-1
        // 中序中以 索引 j+inStart 划分成左右两部分,分别构造左右子树
        root.left = buildTree(pre, in, preStart + 1, inStart, j);
        root.right = buildTree(pre, in, preStart + j + 1, j + inStart + 1, length - j - 1);

        return root;

    }

中序+后序


   public TreeNode buildTreeByInAndPost(int[] in, int[] post) {
        if (in == null || post == null || in.length != post.length) {
            throw new RuntimeException("中序和后序不匹配");
        }
        return buildTreeByInAndPost(in, post, 0, post.length - 1, post.length);
    }


    private TreeNode buildTreeByInAndPost(int[] in, int[] post, int inStart, int postEnd, int length) {
        if (length == 0) return null;
        int j = 0;
        while (j < length && in[j + inStart] != post[postEnd]) {
            j++;
        }
        if (j >= length) {
            throw new RuntimeException("中序和后序不匹配");
        }
        // in[j] 等于 post[postEnd]

        // 左子树的数目 j , 右子树 length-j-1
        int rightSize = length - j - 1;
        TreeNode root = new TreeNode(post[postEnd]);
        root.left = buildTreeByInAndPost(in, post, inStart, postEnd - rightSize - 1, j); // 后序序列的前一部分是左子树节点
        root.right = buildTreeByInAndPost(in, post, inStart + j + 1, postEnd - 1, rightSize);  // 后序序列的后半部分是 右子树节点

        return root;

    }

前序+后序

构造出的二叉树不止一种,返回其中的一种即可

 public TreeNode constructFromPrePost(int[] pre, int[] post) {
        if (pre.length != post.length) {
            throw new RuntimeException("前序和后序不匹配");
        }
        return buildTreeByPreAndPost(pre, post, 0, post.length - 1, pre.length);
    }

    public TreeNode buildTreeByPreAndPost(int[] pre, int[] post, int preStart, int postEnd, int length) {

        if (length == 0) {
            return null;
        }
        if (pre[preStart] != post[postEnd]) {
            throw new RuntimeException("前序和后序不匹配");
        }
        if (length == 1) {
            // 只有一个节点
            return new TreeNode(post[postEnd]);
        }

        TreeNode root = new TreeNode(post[postEnd]);

        int j = 1; // 跳过前序序列第一个元素(根节点)
        while (j < length && pre[j + preStart] != post[postEnd - 1]) j++; //在前序序列中找到 等于后序序列的倒数第二个值(右子树的根节点)
        if (j == length) {
            throw new RuntimeException("前序和后序遍历");
        }

        int leftSize = j - 1;
        int rightSize = length - 1 - leftSize;
        root.left = buildTreeByPreAndPost(pre, post, preStart + 1, postEnd - rightSize - 1, leftSize);
        root.right = buildTreeByPreAndPost(pre, post, preStart + 1 + leftSize, postEnd - 1, rightSize);

        return root;
    }

猜你喜欢

转载自blog.csdn.net/qq1169091731/article/details/85316443