二进制搜索树查找输出

问题描述

我正在尝试为二进制搜索树实现查找功能。如果我查找树的根,它的确会返回true,但是当我查找树中的其他条目时,它会返回false。当我对其进行调试时,该函数似乎返回1,但随后将继续运行,然后最后返回0。据我了解,该函数应在返回任何值后立即终止,因此我不确定为什么会发生这种情况。

int lookup(int n,struct node* x)
{
    if (x->data==n)
    {
        return 1;
    }
    else if (x->left==NULL && x->right==NULL)
    {
        return 0;
    }
    else if (n>x->data && x->right!=NULL)
    {
        lookup(n,x->right);
    }
    else
    {
        lookup(n,x->left);
    }
    return 0;
}

解决方法

您的递归lookup调用返回的值(即lookup(n,x->right);lookup(n,x->left);)将被忽略,即使它是正确的值。
这是因为在函数结束时(即从这些调用之一返回后),您无条件return 0;

要用lookup(n,x->XXX);代替return lookup(n,x->XXX);

,

该函数的行为不正确,因为它在这些if语句中不返回任何内容

    else if (n>x->data && x->right!=NULL)
    {
        lookup(n,x->right);
    }
    else
    {
        lookup(n,x->left);
    }

该控件将被传递到if-else语句之后的最后一个return语句

    return 0;

但是如果您要更新功能

int lookup(int n,struct node* x)
{
    if (x->data==n)
    {
        return 1;
    }
    else if (x->left==NULL && x->right==NULL)
    {
        return 0;
    }
    else if (n>x->data && x->right!=NULL)
    {
        return lookup(n,x->right);
    }
    else
    {
        return lookup(n,x->left);
    }
    return 0;
}

尽管如此,该函数可以调用未定义的行为,因为它不检查指针x是否等于NULL

例如,假设x->data不等于n,而n小于x->data。另外,我们假设x->left等于NULL,而x->right不等于NULL

在这种情况下,第一个if语句的子语句

    if (x->data==n)
    {
        return 1;
    }

将不会执行。

第二个if语句的子语句也将不会执行,因为x->right不等于NULL

    else if (x->left==NULL && x->right==NULL)
    {
        return 0;
    }

第三个if语句将存在相同的问题。

因此控件将在最后的else语句内传递

    else
    {
        lookup(n,x->left);
    }

,其中使用空指针x->left调用该函数。因此,在函数的第二次调用中,您将尝试使用空指针访问内存

    if (x->data==n)
    {
        return 1;
    }

可以通过以下方式编写函数。请注意,由于该函数不会更改树本身,因此它的第二个参数应使用限定符const声明。

int lookup( int n,const struct node *x )
{
    if ( x == NULL )
    {
        return 0;
    }
    else if ( n < x->data )
    {
        return( n,x->left );
    }
    else if ( x->data < n )
    {
        return ( n,x->right );
    }
    else
    {
        return 1;
    }
}

通常,这样的函数也用第一个参数声明,该参数指定指向节点(指向树)的指针,第二个参数指定搜索的对象。就像

int lookup( const struct node *x,int n );

甚至喜欢

_Bool lookup( const struct node *x,int n );
,

您进行了递归调用,但您不返回其结果!

您的代码最简单的递归版本是:

int lookup(int n,struct node* x)
{
    if (x == NULL)
        return 0;

    if (n == x->data)
        return 1;

    if (n < x->data)
        return lookup(n,x->left);
    else
        return lookup(n,x->right);
}

只要它没有脱离分支,它就会测试当前节点-找到该值时,将返回1,否则查找将跳入左分支或右分支。路径结束时(x == NULL,找不到该值,并返回0。

结果从递归返回时向上传播。

最简单的迭代版本:

int lookup(int n,struct node* x)
{
    while (x != NULL)
    {
        if (n == x->data)
            return 1;

        if (n < x->data)
            x = x->left;
        else
            x = x->right;
    }

    return 0;
}

它的工作方式与递归类似,不同之处在于它不会陷入递归,而只是将x指针移到树下。如果在分支端之前找到该值,则返回1。否则,当扫描经过树叶时,结果为0。