二叉树系列7:判断整数序列是不是二叉搜索树的后序遍历结果

来源:互联网 发布:c语言常考题 编辑:程序博客网 时间:2024/05/22 07:54

【要求】输入一个序列,判断这个序列是不是某个二叉搜索树的后续遍历结果。

要判断,首先得分析起床二叉搜索树的后续遍历的特性。由于后续遍历是“左-右-根”,所以:

  • 访问的最后一个节点实际上就是整棵二叉树的根节点root;
  • 然后,找到大于根节点的最小节点 rightMin,在进行后续遍历的时候,rightMin 是右子树的第一个被访问的节点,所以 rightMin 前面的就是 root 的左子树,左子树的节点应该都比 root 小;
  • 这个 rightMin 其实非常好找,因为按照后续遍历,前面第一批输出的左子树,所以,找到的第一个比 root 大的节点就是 rightMin;
  • rightMin 和 root 之间的节点都是右子树的节点,所以,这些节点应该都比 root 大。
  • 然后,二叉搜索树的子树也应该是二叉搜索树,所以在确定了子树的序列后,递归判断它们是不是后续遍历的结果就行了。
    /**     * 判断一个序列是不是某一个二叉搜索树的后续遍历的结果     */    public boolean isPostOrderTraveral(int[] array) {        return isPostOrderTraveral(array, 0, array.length - 1);    }    private boolean isPostOrderTraveral(int[] array, int begin, int end) {        // 只有一个节点为true        if (begin == end) {            return true;        }        int root = array[end];        // 考虑到没有右子树的情况        int rightMin = root;        int indexOfRightMin = end;        for (int i = 0; i < end; i++) {            if (array[i] > root) {                rightMin = array[i];                indexOfRightMin = i;                break;            }        }        // 找到 rightMin 之后,它之前的部分必须都小于root        // 但是上面的查找已经利用了这一性质,也就保证了这一性质,所以不用重复判断        // rightMin 之后到 root 之间的部分是右子树,必须全部大于 root        for (int i = indexOfRightMin + 1; i < end; i++) {            if (array[i] < root) {                return false;            }        }        boolean leftTree;        if (indexOfRightMin != 0) {            leftTree = isPostOrderTraveral(array, begin, indexOfRightMin - 1);        } else {            leftTree = true;        }        // rightMin 之后,root 之前,包括 rightMin 本身,都是右子树的节点        boolean rightTree;        if (indexOfRightMin < end) {            rightTree = isPostOrderTraveral(array, indexOfRightMin, end - 1);        } else {            rightTree = true;        }        return leftTree && rightTree;    }

测试:

    public static void main(String[] args) {        /**         * 通过插入新建了一个二叉搜索树         *                   8         *                 /   \         *                3    22         *                 \   / \         *                 5  13  27         *                  \         *                   7         * */         TreeNode binarySearchTree = new TreeNode(8);        BinaryTreeTest testTree = new BinaryTreeTest();        testTree.add(binarySearchTree, 22);        testTree.add(binarySearchTree, 3);        testTree.add(binarySearchTree, 13);        testTree.add(binarySearchTree, 5);        testTree.add(binarySearchTree, 7);        testTree.add(binarySearchTree, 27);        ArrayList<TreeNode> aList = testTree.postorderTraveral(binarySearchTree);        System.out.println("后续遍历的结果是:");        int[] array = new int[aList.size()];        int count = 0;        for (TreeNode treeNode : aList) {            array[count] = treeNode.val;            System.out.printf("%-5d", array[count]);            count++;        }        System.out.println();        boolean ret1 = testTree.isPostOrderTraveral(array);        System.out.println("Is is a postorderTraveral array? " + ret1);    }

输出:

后续遍历的结果是:7    5    3    13   27   22   8    Is is a postorderTraveral array? true
0 0
原创粉丝点击