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

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

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

  • 访问的最后一个节点实际上就是整棵二叉树的根节点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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值