【算法】判断是否为二叉搜索树

题目来源:

输入:
    2
   / \
  1   4
     / \
    3   5
输出: true
输入:
    5
   / \
  1   4
     / \
    3   6
输出: false

起初使用堆的方式判定是不对的,二叉搜索树的任意结点应该 总大于所有左子树结点以及总小于所有右子树结点,不能只与左右孩子比较。

分析:(两种解法)

  • 方法一:递归求解。设定上下界,如果当前结点在上下界内则是符合的。
  1. 如果是空树,则认为是 BST,返回true
  2. 非空,若 <= 下界 或 >= 上界 则返回false
  3. 以上条件均不满足,则递归判断左右孩子是否为 BST
    • 向左递归时,左孩子应该均小于当前结点,故更新上界为当前结点的值
    • 向右递归时,同理,右孩子均大于当前结点,故更新下界为当前结点数值
bool isValidBST(node* root, int low, int high) {
    if (root == NULL) return true;
    if (root->val <= low || root->val >= high) return false;
    return isValidBST(root->left, low, root->val)
        && isValidBST(root->right, root->val, high);
}

int main() {
    node *root = initBinaryTree();
    isBST(root, INT_MIN, INT_MAX);
    return 0;
}

调用时,初始的上下界为整型可表示的最小最大值。

  • 方法二:迭代。二叉搜索树的中序遍历序列是升序的,只需要判断中序序列中两个相邻元素的大小关系即可,使用preValue记录前一个结点的值。
bool isValidBST(node* root) {
    stack<node*> s;
    node* p = root;
    long preValue = LONG_MIN;	// 定义最小值
    while (!s.empty() || p != NULL) {
        for (;p != NULL; p = p->left) s.push(p); // 左孩子不为NULL, 一直入栈
        p = s.top();
        s.pop();
        if (p->val <= preValue) return false;	// 如果不符合则直接返回 false
        preValue = p->val;
        p = p->right;
    }
    return true;
}
  • 方法三:同为递归求解,但相对耗时。根据BST性质,判断当前节点是不是总比左子树的最右端的孩子大且总比右子树的最左端孩子小。缺点是对任意结点总要查找一次上面描述的最左右端的结点。
bool isValidBST(TreeNode* root) {
    if (root == NULL) return true;
    TreeNode* p = root->left;
    if (p) {
        while (p->right) p = p->right;
        if (root->val <= p->val) return false;
    }
    p = root->right;
    if (p) {
        while (p->left) p = p->left;
        if (root->val >= p->val) return false;
    }
    return isValidBST(root->left) && isValidBST(root->right);
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值