二叉搜索树的后序遍历--递归方法处理

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

http://www.nowcoder.com/questionTerminal/a861533d45854474ac791d90e447bafd

[编程题] nk:[二叉搜索树的后序遍历]

输入输出

思路

结合题解中这位同学画的图的分析https://www.nowcoder.com/questionTerminal/a861533d45854474ac791d90e447bafd?answerType=1&f=discussion
图片说明
代码思路:

我们可以采用递归的思想,每次处理本次流程的时候(比如该组元素有n个),拿出最后一个节点当作是root节点,然后,在剩下的n-1 中,确定出前边的左子树部分都比root小左子树后的右子树部分都比roo大

比如:一开始调用传入的是solve(arr,left,right);

(1)此时,我们得到本次的root = arr[right];

​ 指定一个用于比较指向的指针int i=0;

​ 指定一个变量split 用于记录本次的分割点(分割左 右子树)

(2)在指针i从本次的数组的left处,一直判断,如果arr[i]<root ,就指针右移;当找到了arr[i]>root的时候,指针就是指向了右子树的部分的第一个元素了。 【这里也有可能就是指针走到了right-1的那个元素了,也没找到比root大的元素,就是仅有左子树,无右子树的情况,需要考虑进去,如果是仅有左子树无右子树,那就无分割无需递归这组数据产生的左子树和右子树是否满足的了,直接返回true】

(3)此时继续让指针移动往后判断右子树情况。如果arr[i]>root,就正常i++后移。当到达了right-1的那个节点就是比较完了右子树,说明本次的左右部分都满足二叉树的情况。那接下来就是需要对本次这组数据分割的两部分子树进行上述逻辑判断了,如果也满足,那这组数据就返回true

  • 当在右子树的判断过程中,如果出现了arr[i]<root的话(即右子树小于root的情况),直接返回false,本组数据肯定不满足二叉排序树。

Java代码(递归处理)

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
       return  verify(sequence,0,sequence.length-1);
    }

    public boolean verify(int[] seq,int left,int right){
        //极端条件处理
        if(seq==null || seq.length==0) {return false;}

        //===================递归的退出条件===================
        if(left>=right){
            return true;
        }

        //===================递归的处理方法体=====================
        int root = seq[right];  //根永远都是子树的最右边的那个节点
        int i = left;  //用于元素比较的指针
        int split = 0; //标记大小分界点,用于递归传参

        //处理判断左子树,从头开始找,如果当前值小于root,指针右移
        while(i<right && seq[i]<root){
           i++;
        }

        //标记切割点(此时指针i指向了右子树的第一个大于root的节点)
        split = i;

        //判断右子树
        if(i>=right){
            //说明在上边的查找左子树的中已经走到头了,该次没有右子树,且左子树都小于root
            return true; //仅有左子树无右子树也无序递归了,直接返回这组数据满足
        }else{
            //如果还没到头,那就继续比较看是否都是大于root的节点
            while(i<right){
                if(seq[i]>root) {i++;}
                else{return false;}  //存在不满足的情况直接返回了false;
             }
        }
        //递归子树(正常退出了上述的while,那么就是此次满足,递归遍历该次分割的子树,两子树都满足则满足)
        return verify(seq,left,split-1) && verify(seq,split,right-1);
    }
}

输出:
图片说明

全部评论
第31行我认为不应该直接返回true,虽然没有右子树了,但是左子树中会存在着不是搜索二叉树的可能性,虽然可以通过用例但是不严谨,应该返回继续递归左子树。
点赞 回复 分享
发布于 2021-01-02 19:56

相关推荐

牛客76783384...:字节:不要放箭,活捉赵子龙
点赞 评论 收藏
分享
2025-12-13 21:01
已编辑
百度_meg_前端开发(实习员工)
走到这一步,确实有些意外。先简单说说我的情况,我是双非本,大一那年对后端兴趣特别浓,学了快一年半。但不知为什么越往后学兴趣越淡——大概到分布式那块,比如nacos、卡夫卡这些,感觉越来越吃力。再加上看到师兄师姐在后端方向上的碰壁(现在是大go时代),在和师兄师姐商量后我在今年一月左右转前端了或许是因为有java的基础,对项目开发流程有些概念,前端三件套我过得比较快。之后学了Vue,动手做了自己的博客,这大概也是我转前端的一个重要原因吧,一直很想拥有一个属于自己的个人博客,能按自己的想法去设计、实现,并长期迭代完善,这种成就感真的很棒。之前拿过别人的开源项目来更改&nbsp;但是自己修改的就是一坨,那个时候缺少对前端代码的理解&nbsp;就算借助ai做出来的效果也是一坨就这样到了大二暑假,我觉得该找份实习,丰富一下简历了。我自认不是很有创造力的人,平时少有自发的项目灵感,所以更希望通过实习开阔眼界、提升能力。一开始投递和面试的过程挺煎熬的,或许是因为目标多是中小厂,很多hr已读不回,或是直接砍半薪资问我接不接受。面试时也常觉得像在走流程,问的都是八股文,有的面试官还会边看题边问,甚至有一次十分钟就结束了,好在最后钛动给了我机会。实习期间我学到了很多,虽然也常被拷打,还好ld会帮我收拾烂摊子。从钛动离职回校后,我半推半就地背八股、学新技术,无聊时就刷里扣、看看牛客和biss。原本以为双非bg很会被hr速度筛掉所以就尝试性的投了纷享销客和百度的日常实习,没想到最后两家都oc了,雷姆了家人们,双非鼠鼠居然圆了大厂梦yysy,这一路其实冒了不小的风险。毕竟学了那么久的后端,大学四年时间有限,突然转前端,意味着很多积累的知识可能用不上了。但我很庆幸当时有放下的勇气。无论过去做了什么选择,我都想感谢当时的自己,因为那份勇气,才走到了今天。同时也很感谢这一路师兄师姐的帮忙,师兄帮忙模拟面试,提供资料,师姐教我如何选择岗位,如何处理实习带来的问题马上就要北漂了,对未来是充满了期待也存在着恐惧,南方人头一次去这么远的地方,每天都能看到雪,可以跟实力强劲的同事合作,想想都很兴奋,但是也害怕自己不能胜任这份工作会被压力到爆,但是不管怎么样大家一起互勉吧,呆在舒适区只会停滞不前,压力才能带来成长
牛马人的牛马人生:勇敢追梦
2025年终总结
点赞 评论 收藏
分享
评论
3
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务