查找二叉树是否为二叉搜索树

时间:2012-05-31 11:13:55

标签: algorithm binary-tree binary-search-tree

今天我接受了一次采访,我被要求编写一个采用二叉树的程序,如果它也是二进制搜索树则返回true,否则为假。

我的方法1:执行有序遍历并将元素存储在O(n)时间内。现在扫描数组/元素列表,检查i th 索引处的元素是否大于(i + 1) th 索引处的元素。如果遇到这种情况,则返回false并退出循环。 (这需要O(n)时间)。最后返回true。

但这位先生希望我提供一个有效的解决方案。我尝试了但是我没有成功,因为要查找它是否是BST我必须检查每个节点。

此外,他指着我思考递归。 我的方法2:如果对于任何节点N N> left是

但这会很复杂,而且运行时间似乎并不好。如果您知道任何最佳解决方案,请提供帮助。

7 个答案:

答案 0 :(得分:78)

以下答案是一个众所周知的问题:

public boolean isValid(Node root) {
     return isValidBST(root, Integer.MIN_VALUE,
          Integer.MAX_VALUE);
}
private boolean isValidBST(Node node, int l, int h) {
     if(node == null)
         return true;
     return node.value > l 
         && node.value < h
         && isValidBST(node.left, l, node.value)
         && isValidBST(node.right, node.value, h);
}

递归调用确保子树节点在其祖先的范围内,这很重要。运行时复杂度为O(n),因为每个节点都要检查一次。

另一个解决方案是进行inorder遍历并检查序列是否已排序,尤其是因为您已经知道提供了二叉树作为输入。

答案 1 :(得分:7)

@Dhruv提供的答案很好。除此之外,这是另一种在O(n)时间内工作的解决方案。
我们需要在这种方法中跟踪前一个节点。在每次递归调用中,我们使用当前节点数据检查先前的节点数据。如果当前节点数据小于先前,我们返回false

int isBST(node* root) {
  static node* prev  = NULL;

  if(root==NULL)
    return 1;

  if(!isBST(root->left))
    return 0;

  if(prev!=NULL && root->data<=prev->data)
    return 0;

  prev = root;
  return isBST(root->right);
}

答案 2 :(得分:1)

boolean b = new Sample().isBinarySearchTree(n1, Integer.MIN_VALUE, Integer.MAX_VALUE);
.......
.......
.......
public boolean isBinarySearchTree(TreeNode node, int min, int max){
  if(node == null){
    return true;
  }

  boolean left  = isBinarySearchTree(node.getLeft(), min, node.getValue());
  boolean right = isBinarySearchTree(node.getRight(), node.getValue(), max);

  return left && right && (node.getValue()<max) && (node.getValue()>=min);      
}

邀请评论。感谢。

答案 3 :(得分:0)

我认为第二种方法是正确的。树可以以递归方式遍历。在每次迭代时,可以存储当前子树的下限和上限。如果我们想用root x检查子树,并且子树的边界是l和h,那么我们所需要的只是检查l&lt; = x&lt; = h并检查带有边界l和x的左子树,并且正确的边界x和h。

这将具有O(n)复杂性,因为我们从根开始,并且每个节点仅作为某个子树的根检查一次。此外,我们需要O(h)内存用于递归调用,其中h是树的高度。

答案 4 :(得分:-1)

上面有一些使用INTEGER.MAX AND MIN的例子 我看不出有理由通过它们及其意义, 如果我错了,请纠正我或解释原因。

更多二进制搜索树可能包含通过compareTo方法或Coperator进行比较的对象..(因此Integer.MIN和Integer.MAX不适合该模型) 我正在编写一个返回true或false的代码 一个人必须调用(root_node,true),如果是bst,则返回true

void boolean isBSt( node root_node, boolean passed_root)
{

  if ( node==null){
        if ( passed_root)
        return false;
        // you have passed null pointer as 
        //root of the tree , since there is no 
        // valid start point we can throw an exception or return false      
        return true;
   }

  if( node.right !=null ) 
     if ( node.right.data <= node.data)
   return false;

  if ( node.left !=null ) 
        if ! ( node.left.data <= node.data) 
    return false;

  return ( isBST( node.right , false) && isBST( node.left, false ) )

}

答案 5 :(得分:-1)

看看这个解决方案: http://preparefortechinterview.blogspot.com/2013/09/am-i-bst.html

它解释了不同的方法,并为您提供了一种通用且有效的方法。希望它有所帮助。

答案 6 :(得分:-2)

这是另一个解决方案,它使用2个辅助函数,使用辅助函数minValue和maxValue

为每个节点计算子树中的最小值和最大值
int isBST(struct node* node)
    {
      if (node == NULL)
        return(true); 

      /* false if the max of the left is > than us */
        if (node->left!=NULL && maxValue(node->left) > node->data)
            return(false); 

      /* false if the min of the right is <= than us */
        if (node->right!=NULL && minValue(node->right) < node->data)
            return(false); 

      /* false if, recursively, the left or right is not a BST */ 
         if (!isBST(node->left) || !isBST(node->right))
           return(false); 

      /* passing all that, it's a BST */
          return(true);
    }