如何确定二进制树是否为BST

时间:2018-06-03 03:54:37

标签: c# data-structures tree binary-tree binary-search-tree

我试图找出一个逻辑来确定二进制树是否是BST。我想使用inorder方法,并且我不想使用额外的数组来存储所有传入的值,因为我们知道Inorder应该按排序顺序。我想检查传入的值,而不必将其存储在一个数组中。以下是我的尝试无效。

   public bool CheckBST(BstNode root)
        {
            BstNode prev = new BstNode(Int32.MinValue);
            if (root == null)
                return true;
            if (root.left != null)
            {
                return CheckBST(root.left);
            }
            if (prev != null && prev.data >= root.data) // means data  is not sorted hence NOT   BST
                return false;
            prev = root;
            if(root.right!=null)
            {
                return CheckBST(root.right);
            }
            return true;
        }

6 个答案:

答案 0 :(得分:1)

给定二叉树,以下确定它是否是有效的二叉搜索树(BST)。

  • 节点的左子树仅包含键小于的节点 节点的密钥。
  • 节点的右子树仅包含键大的节点 而不是节点的密钥。
  • 左右子树也必须是二叉搜索树。

让我们看下面的例子:

enter image description here

如果您看到上面的二进制树是BST。

现在让我们看另一个例子:

enter image description here

根节点的值为5,但其右子的值为4,不满足上述条件。所以给定的树不是BST。

解决方案代码:

鉴于TreeNode被定义为

public class TreeNode 
{
    public int Val { get; set; }
    public TreeNode Left { get; set; }
    public TreeNode Right { get; set; }
    public TreeNode(int x) { this.Val = x; }
}

检查验证的代码是

public bool IsValidBST(TreeNode root) 
{
    return IsValidBST(root, int.MinValue, int.MaxValue);
}

private bool IsValidBST(TreeNode root, int minValue, int maxValue)
{
    if (root == null)
    {
        return true;
    }

    int nodeValue = root.Val;
    if (nodeValue < minValue || nodeValue > maxValue)
    {
        return false;
    }

    return IsValidBST(root.Left, minValue, nodeValue - 1) && IsValidBST(root.Right, nodeValue + 1, maxValue);
}

现在可以使用根节点

调用IsValidBST
 bool isValidBST = IsValidBST(rootNode);

答案 1 :(得分:0)

因此,通常在BST中,每个节点中有三件事。那是数据,左右两个指针。如果任何节点中有两个以上的指针可用,则它不是BST。最好在节点级别确定是否有更多的指针。你会通过搜索树来浪费时间和资源。

这是一个很好的方法https://www.geeksforgeeks.org/a-program-to-check-if-a-binary-tree-is-bst-or-not/

答案 2 :(得分:0)

您无法在prev中每次初始化CheckBST。您可以使prev全局。此外,我已将prev设为integer类型。

int prev = Int32.MinValue; //made this global and integer type

public bool CheckBST(BstNode root) {
 if (root == null)
  return true;
 bool isLeftBST = CheckBST(root.left);
 if (isLeftBST == false) return false;

 if (prev != Int32.MinValue && prev >= root.data) // means data  is not sorted hence NOT   BST
  return false;

 prev = root.data; //mark the prev before traversing the right subtree

 return isLeftBST && CheckBST(root.right);

}

忽略语法问题,如果有的话。我尝试了更多伪代码。

当然,还有其他方法可以解决这个问题。就像到目前为止跟踪最小值和最大值一样(在@ user1672994答案中)。

答案 3 :(得分:0)

如果你可以让CheckBST返回被检查BST的范围(min,max),那么下面的递归函数应该这样做:

// Defines the return value that represents BST check failure.
const pair<int, int> kCheckFailed(Int32.MaxValue, Int32.MinValue);

pair<int, int> CheckBST(const BstNode& curr)
{
  pair<int, int> left_ret(curr.value, curr.value);
  pair<int, int> right_ret(curr.value, curr.value);

  // Makes sure the left subtree, if any, is a BST, and its max
  // (`left_ret.second`) is no greater than `curr.value`
  if (curr.left) {
    left_ret = CheckBST(*curr.left);
    if (left_ret == kCheckFailed || left_ret.second > curr.value)
      return kCheckFailed;
  }

  // Makes sure the right subtree, if any, is a BST, and its min
  // (`right_ret.first`) is not less than `curr.value`.
  if (curr.right) {
    right_ret = CheckBST(*curr.right);
    if (right_ret == kCheckFailed || right_ret.first < curr.value)
      return kCheckFailed;
  }

  // Returns range by combining min of left subtree and max of right subtree.
  return make_pair(left_ret.first, right_ret.second);
}

请注意CheckBST通过引用获取(子)树根,以确保节点(curr)始终有效。但是,curr.leftcurr.right可能仍然为NULL,在这种情况下,相应的最小值或最大值分别仅为curr.value,初始化为ret_left和{ {1}}。

答案 4 :(得分:0)

  • 时间复杂度为 O(1)的递归。

  • 删除注释行,以查看其调用方式。

  • 对于首次通话isBST(root, null, null)

    public bool isBST(Node root, Node l, Node r)
    {
            // Console.WriteLine($"Processing: isBST({root?.data}, {l?.data}, {r?.data})");
            if (root == null) return true;
    
            if (l != null && root.data <= l.data) return false;
    
            if (r != null && root.data >= r.data) return false;
    
            // Console.WriteLine($"isBST({root?.left?.data}, {l}, {root?.data}) && isBST({root?.right?.data}, {root?.data}, {r?.data})");
            return isBST(root.left, l, root) && isBST(root.right, root, r);
    }
    

答案 5 :(得分:-1)

您不需要上一步

  1. 递归检查max(left)是否小于或等于root。

  2. 递归检查min(右)是否大于root。

  3. 检查左边是BST。

  4. 检查权利是否为BST。

  5. 当然,在需要的地方检查空值。