剑指offer学习笔记(3)--根据后序遍历判断是否二叉搜索树

考点:二叉搜索树、后序遍历

 

题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。如数组{5,7,6,9,11,10,8}是如下二叉树的后序遍历,是二叉搜索树。

知识点复习

1.特殊二叉树:

(1)满二叉树:二叉树中,所有分支都有左右孩子,且叶子节点在同一层

(2)完全二叉树:编号为i的节点与满二叉树编号同样为i的节点位置相同

         特点:

  •        叶子节点只出现在最下两层
  •        最下层叶子节点在左部,倒数第二次叶子节点在右部
  •        不存在只有右子树情况

(3)二叉搜索树(二叉查找树、二叉排序树): 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。

2.二叉树遍历:

前序:根左右

中序:左根右

后序:左右根

本题分析思路

在后序遍历中,最后一个数字是树的根节点。数组前面的数字,第一部分是左子树节点,都比根节点小;第二部分是右子树节点,都比根节点大。突破点先确定根节点,通过遍历比root小的值确定左部分;剩下右部分中,一旦有小于root,则不是二叉搜索树。递归判断左右子树。

实现代码

public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        return bst(sequence,0,sequence.size()-1);
    }
private:
    bool bst(vector<int> seq,int begin,int end){
        if(seq.empty()||begin>end)
            return false;
        int root=seq[end];   //后序遍历最后一个数必是根节点
        int i=begin;
        //遍历左孩子值都小于root
        for(;i<end;i++){
            if(seq[i]>root)
                break;
        }
        //一旦有大于root的值开始遍历右孩子(j从i开始)
        int j=i;
        for(;j<end;j++){
            if(seq[j]<root)
                return false;
        }
        bool left=true;
        bool right=true;
        //左右递归
        if(i-1>begin)
            left= bst(seq,begin,i-1);
        if(i<end-1)
            right=bst(seq,i,end-1);
        return left&&right;
    }

方法2

bool VerifySquenceOfBST(vector<int> sequence) {
        if(sequence.empty())
            return false;
        return bst(sequence,0,sequence.size()-1);
    }
    bool bst(vector<int> seq,int begin,int end){
        //递归结束条件(到最底层)
        if(begin >=end)
            return true;
        int root=seq[end];
        int i=begin;
        for(;i<end;i++){
            if(seq[i]>root)
                break;
        }
        int j=i;
        for(;j<end;j++){
            if(seq[j]<root)
                return false;
        }
        return bst(seq,begin,i-1) && bst(seq,i,end-1);
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值