从定义出发,理解二叉搜索树

[leetcode Validate Binary Search Tree]从定义出发,理解二叉搜索树

96 书呆子的复仇 关注

2015.12.13 12:53* 字数 855 阅读 181评论 0喜欢 2

附上原题:

一棵二叉树如果属于二叉搜索树,必须满足三个条件:

  1. 左子树的所有节点都小于根节点
  1. 右子树的所有节点都大于根节点
  2. 左子树跟右子树同时也是二叉搜索树

我们看到第三条定义本身也是递归的。那根据该定义,如何来检验一棵二叉树到底是不是二叉搜索树?

首先,如果左子树跟右子树其中有一棵不是二叉搜索树的情况下,则该二叉树必定不属于二叉搜索树。那如何判定左子树跟右子树是不是二叉搜索树呢?好像我们又回到了原来的问题。看一种比较特殊的情况,假如说二叉树只有一个节点,即没有左子树也没有右子树,那么它必定属于二叉搜索树。如果左子树不存在,右子树存在的情况下呢?此时左子树就不需要再考虑是不是二叉搜索树了。反之右子树不存在的情况下也一样。

因此,对于这个问题,我们可以先考虑一棵二叉树的叶子节点。比如说有这样一棵二叉树:

左子树跟右子树都属于叶子节点,必定是二叉搜索树。在符合第三条定义的情况下,再来看前面两条。根节点大于左子树的所有节点,难道要用根节点与左子树的每个节点去比较?我们换个角度想,是不是只要根节点大于左子树最大的节点就可以了?因为在确定左子树属于二叉搜索树的情况下,只要沿着左子树的根节点出发一直向右即可找到最大的节点。同样,对于第二个定义,根节点只需小于右子树最小的节点即可。

我们运用了一种“分而治之”的思想,先考虑最基本的情况,即叶子节点,再得到左子树和右子树同时为二叉搜索树的前提下,用当前树的根节点去比较左子树的最大值和右子树的最小值。然后算法不断得往上回溯,最终得出整棵树是不是二叉搜索树。

根据以上分析,我们设计出如下算法:

  1. 如果当前节点即不存在左子树也不存在右子树,直接返回true。
  1. 如果当前节点存在左子树,则验证左子树是否为二叉搜索树,若是,并且根节点大于左子树的最大值,则左子树验证通过。若左子树不存在,同样验证通过。
  2. 如果当前节点存在右子树,则验证右子树是否为二叉搜索树,若是,并且根节点小于右子树的最小值,右子树验证通过。若右子树不存在,同样验证通过。
  3. 若左子树跟右子树同时验证通过,返回true;否则,返回false。

看代码:

class Solution {
public:
    bool isValidBST(TreeNode* root) {

        bool isValidLeft = true;
        bool isValidRight = true;
        if (root) {
            int val = root->val;
            if (root->left) {
                //验证左子树是否为二叉搜索树,并且根节点大于左子树的最小值
                isValidLeft = isValidBST(root->left) && (val > fetchMaxNodeVal(root->left));
            }
            if (root->right) {
                isValidRight = isValidBST(root->right) && (val < fetchMinNodeVal(root->right));
            }

            if (!root->left && !root->right) {
                return true;
            }
        }
        return isValidLeft && isValidRight;
    }
private:
    //获取二叉树的最大值
    int fetchMaxNodeVal(TreeNode *node) {
        while (node->right) {
            node = node->right;
        }
        return node->val;
    }

    int fetchMinNodeVal(TreeNode *node) {
        while (node->left) {
            node = node->left;
        }
        return node->val;
    }
};

小礼物走一走,来简书关注我

猜你喜欢

转载自blog.csdn.net/jfkidear/article/details/84173823