如何检查树是否是BST?

时间:2014-12-01 21:23:50

标签: c++ binary-tree binary-search-tree

我必须检查树是否是二叉搜索树。我正在使用带有临时数组的inorder遍历来收集值。我必须检查数组是否是升序,如果是,那么我返回true:

bool myisBST(Node* node, std::vector<int> v);

bool myisBST(Node* node)
{
    return myisBST(node, std::vector<int>());
}

bool myisBST(Node* node, std::vector<int> v)
{
    if (node)
    {
        if (node->left)
            return myisBST(node->left, v);

        v.push_back(node->data);

        if (node->right)
            return myisBST(node->right, v);
    }

    return std::is_sorted(v.begin(), v.end());
}

当二叉树是这样的时候:

            50
           /  \
         25    75
        /  \   / \
       1   12 62 -99

正如您所看到的,-99使这不是二叉搜索树,但它仍然返回true。我的实施有问题吗?

Demo

4 个答案:

答案 0 :(得分:3)

两个问题:

  1. myisBST中,您通过传递v,而不是通过引用传递,因此当您递归传递向量时,对其进行的更改不会t在调用方法中更改其值。只需将功能签名更改为bool myisBST(Node* node, std::vector<int>& v)即可解决此问题。
  2. 您应该返回的值是矢量是否已排序(正如您在方法的最后一行中所做的那样),而是通过编写return myisBST(node->left, v);return myisBST(node->right, v);来提前返回。您实际上并不对这些方法的返回值感兴趣;你只是用它们来按顺序填充矢量。从这两行中删除return
  3. 遵循这两个修复程序,您的方法可以正常工作。

答案 1 :(得分:1)

首先,你应该通过引用传递vector,否则每个递归调用都会获得一个副本,因此原始向量可能是空的。

其次,您甚至不需要先创建矢量然后再进行检查,您只需检查每个节点的BST属性,即根必须大于左子节点且小于正确的孩子,例如,

bool isBST(const Node* root, vector<int>* v) {
  if (!root) { return true; }

  bool leftBST = true;

  if (root->left) {
    if (root->data > root->left->data) {
      leftBST = isBST(root->left, v);
    } else {
      // the current node violates the BST precondition
      return false;
    }
  }

  // push the root
  v->push_back(root->data);
  // return false if left subtree is not a BST
  if (!leftBST) return false;

  if (root->right) {
    if (root->data < root->right->data) {
      // return whether or not the right subtree is a BST
      return isBST(root->left, v);
    } else {
      // the current node violates the BST precondition
      return false;
    }
  }

  // everything good, this is a BST
  return true;
}

答案 2 :(得分:0)

C ++程序检查树是否为BST

struct Node
{
    int data;
    struct Node* left, *right;
};

bool IsBST(Node* ObjNode)
{
    bool leftBST = false;

    bool rightBST = false;

    if( ObjNode->left != null && ObjNode-left < objNode->data)
    {
        leftBST = IsBST(ObjNode->left)
    }
    else if( ObjNode->left == null)
    {
        leftBST = true;
    }

    else if( ObjNode->left != null  && ObjNode-left >= objNode->data)
    {
        leftBST = false;
    }


    if( ObjNode->left != null && ObjNode-left < objNode->data)
    {
        rightBST = IsBST(ObjNode->right)
    }
    else if( ObjNode->right == null)
    {
        rightBST = true;
    }

    else if( ObjNode->right != null  && ObjNode-right >= objNode->data)
    {
        rightBST = false;
    }


    return (leftBST && rightBST );

}

答案 3 :(得分:0)

在先前的解决方案中,他们会保留有序遍历的列表,您确实不需要它,可以继续检查最后一个遍历的元素并继续前进。

  

下面的解决方案是fastest

enter image description here

class Solution {
    int lastval = Integer.MIN_VALUE;
    int count = 0;
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;
        boolean left = isValidBST(root.left);
        if(!left){
            return false;
        }
        int rootVal = root.val;
        if(rootVal == -2147483648 && count == 0 ){
            rootVal = rootVal + 1;
        }
        if( rootVal <= lastval){
           return false; 
        }
        count ++;
        lastval = root.val;
        boolean right = isValidBST(root.right);
        if(!right){
            return false;
        }
        return true; 
    }
}