如何验证二进制搜索树?

时间:2012-03-12 12:49:31

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

以下是我为验证BST而编写的代码。

这是对的吗?如果没有,我该怎么做?

int validate(node *root)
{
    if(root==NULL) return 1;
    else if(root->lchild!=NULL && (root->lchild)->data >=root->data) return 0;
    else if(root->rchild!=NULL && (root->rchild)->data <=root->data) return 0;
    validate(root->lchild);
    validate(root->rchild);
    return 1;
}

2 个答案:

答案 0 :(得分:5)

考虑树

    10
   /  \ 
 8    15
/ \   /
3  9 4 

在此树中,无处不在root->left->data < root->dataroot->right->data > root->data

但是树不是BST,因为节点4不在正确的位置(它大于10,这是无效的。)

如果您必须验证BST,您应该能够找出条件:

  • 左子树中的最高值&lt;最低价值是正确的子树

答案 1 :(得分:1)

假设你有以下树:

      20
     /  \
   10    30
  /
15

从你的代码的根开始:

1 int validate(node *root) {
2     if(root==NULL) return 1;
3     else if(root->lchild!=NULL && (root->lchild)->data >=root->data) return 0;
4     else if(root->rchild!=NULL && (root->rchild)->data <=root->data) return 0;
5     validate(root->lchild);
6     validate(root->rchild);
7     return 1;
8 }

现在前三个if语句(第2行到第4行)不会在根节点“触发”,因为树的前两个级别是正常的(左侧节点小于20且右侧节点大于20)。因此,您尝试通过第5行的递归调用验证左子树(包含10的节点)。

在那个电话中,它没关系,因为它的左节点(15)比它大,而第3行将返回零表示它是坏的。

但是,因为你已经调用validate抛弃了返回值,它只是继续到第6行然后最终在最后一行7上返回1,即使树是是有效。

您需要做的是将较低级别的结果传递给较高级别,以便对其进行操作。

你也可以摆脱那些else if的东西,因为它们在返回后没用,而且我不是在这种情况下使用变量root的忠实粉丝,因为它只是在递归的最高级别(可能会混淆一些)。

我会选择(带有适当的评论):

int validate (node *testNode) {
    // Terminal case, empty sub-tree is valid.

    if (testNode == NULL)
        return 1;

    // Left node >= current means invalid

    if (testNode->lchild != NULL)
        if (testNode->lchild->data >= testNode->data)
            return 0;

    // Right node <= current means invalid

    if (testNode->rchild != NULL)
        if (testNode->rchild->data <= testNode->data)
            return 0;

    // Invalid entire left subtree means invalid.

    if (! validate (testNode->lchild))
        return 0;

    // Otherwise return state of entire right subtree.
    return validate (testNode->rchild);
}

您可能还想考虑是否需要树中的重复值。如果您这样做,则比较应为<>,而不是<=>=