二叉排序树

二叉排序树(Binary Sort Tree),又称二叉查找树。它是一颗空树,或者具有下列性质:

若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树分别为二叉排序树。

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

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

参考以下这颗二叉搜索树:

    5
   /  \    
  2   6   
 /      \  
1        3

示例 1:

输入: [1,6,3,2,5] 输出: false

示例 2:

输入: [1,3,2,6,5] 输出: true

递归分治
//因为是后序遍历:左右根, 所以最后的一定是根节点 ,二叉排序树的左子树都小于根节点,右子树反之。利用好这两个特征就可以证明

class Solution {
    public boolean verifyPostorder(int[] postorder) {
        return recur(postorder, 0, postorder.length - 1);
    }
    boolean recur(int[] postorder,int i, int j){  //在i j这个区间 (也就是说确定i-j这个坐标的树是否符合二叉搜索树)
        if(i >= j){  //前面的坐标大于等于后面的坐标, 说明树的结点只剩一个或者不剩了.
            return true;
        }
        int p = i; //p是负责遍历的坐标 (从i开始)
        while(postorder[p] < postorder[j]) p++;
        int m = p; //如果发现大于尾结点的数(则这个数及之后都是右子树)
        while(postorder[p] > postorder[j]) p++;  //(右子树的所有子节点都应该大于根节点
        //如果遍历结束之后,发现有小于根节点的节点存在,则不符合条件
        //接下来一直遍历,直到最后一层叶子节点
        return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);//(第二次分层的时候记得把根节点滤除, 所以到 j - 1)
辅助单调栈
//就是找子树的分叉点,保证root一直是正在经历分叉的树的最大点,在下一次分叉之前,保证所有元素都小于这个最大点。
//找的第一个分叉点(一直向右下探索(数组为递增) 找到最大点,然后就是最大点的同层左子树,因为最小子树(也就是只有两个点),是最右端的,所以她的同层左子树也是出了该点的最大的值(所以也就把root换成左子树了),然后一直向上遍历相对最右子树的左节点,直到遍历完了整个大二叉树的右子树,在遍历这样大二叉树左子树,如果该数组符合这些,则成立。)
//遍历 postorderpostorder 所有节点,各节点均入栈 / 出栈一次,使用 O(N) 时间。
class Solution {
    public boolean verifyPostorder(int[] postorder) {
        Stack<Integer> stack = new Stack<>();
        int root = Integer.MAX_VALUE;          
        for(int i = postorder.length - 1; i >= 0; i--){ //倒叙分别是根 右 左  (如果没遇到递减说明一直在增,也就是一直在右子树.)
        //一直把右子树遍历到底,所以当前的结点一直都是同一层的左子树或者下一层的右子树()
            if(postorder[i] > root) return false;      //右 > 根 > 左  这个序列会全部入栈()所以 root应当是当前的根或者右子树
            //他会一直向右下方向,直到遍历到最右下的那个小二叉树时发现递减。
            while(!stack.isEmpty() && stack.peek() > postorder[i]){   界                                                                           
                root = stack.pop();   //往回出栈,因为此时是未检测过的最右的子树的左节点,所以当找到小于此节点应该就是父节点的根节点,所以此时的root为这个分叉的左节点的父节点
            }
            //将这个左节点入栈(此时root最大,这个节点第二大。)
            stack.add(postorder[i]); //无论怎样都倒序入栈
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值