跳至主要內容

二叉搜索树的后续遍历序列

soulballad算法剑指Offer剑指Offer约 701 字大约 2 分钟

题目:

​ 输入一个整数数组,判断该数组是不是某个二叉搜索树的后续遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。例如,输入数组 {5, 7, 6, 9, 11, 10, 8},则返回 true,因为这个整数序列是下图中二叉搜索树的后续遍历结果。如果输入的数组是 {7, 4, 6, 5},则由于没有哪棵二叉树的后续遍历结果是这个序列,因此返回 false。

1569910695927

分析:

​ 在后序遍历序列中,最后一个数字是树的根节点。数组中前面的数字可以分为两部分:第一部分是左子树节点的值,它们都比根节点的值小;第二部分是右子树节点的值,它们都比根节点的值大。

​ 以数组 {5, 7, 6, 9, 11, 10, 8} 为例,后序遍历结果的最后一个数字 8 就是根节点的值。在这个数组中,前 3 个数字 5、7、6 都比 8 小,是 8 的左子树节点;后 3 个数字9、11、10 都比 8 大,是 8 的右子树节点。

​ 接下来以同样的方法来确定与数组每一部分对应的子树的结构。这其实是一个递归的过程。对于序列 {5, 7, 6} 来讲,最后一个数字 6 是左子树根节点的值。数字 5 比 6 小,是 6 的左子节点,而 7 则是 6 的右子节点。同理,在序列 {9, 11, 10} 中,10 是右子树的根节点, 9 是 10 的左子节点, 11 是 10 的右子节点。

代码:

public class CheckSearchTreeSequence {

    /**
     * 是否二叉搜索树的后序遍历序列
     *
     * @param sequence 数组序列
     * @param length   数组长度
     * @return
     */
    public static boolean isPostOrder(int[] sequence, int length) {

        if (null == sequence || length <= 0) {
            return false;
        }

        // 左右子树分界index
        int separateIndex = 0;
        // 根节点的值
        int root = sequence[length - 1];

        // 二叉搜索树中左子树节点的值小于根节点的值
        for (int i = 0; i < length; i++) {
            if (sequence[i] > root) {
                separateIndex = i;
                break;
            }
        }

        // 二叉搜索树中右子树节点的值大于根节点的值
        for (int i = separateIndex; i < length; i++) {
            if (sequence[i] < root) {
                return false;
            }
        }

        // 判断左子树是否二叉搜索树
        boolean left = true;
        // 判断右子树是否二叉搜索树
        boolean right = true;

        if (separateIndex > 0) {
            left = isPostOrder(sequence, separateIndex);
        }

        // 判断右子树时从序列中排除根节点
        if (separateIndex < length - 1) {
            right = isPostOrder(sequence, length - separateIndex - 1);
        }

        return left && right;
    }
}

测试:

public class TestCheckSearchTreeSequence {

    @Test
    public void test() {
        int[] sequence = {5, 7, 6, 9, 11, 10, 8};
        int length = 7;

        System.out.println(CheckSearchTreeSequence.isPostOrder(sequence, length));
    }
}
上次编辑于:
贡献者: soulballad