【问题标题】:C: binary tree searching methodC:二叉树搜索法
【发布时间】:2012-05-15 13:53:49
【问题描述】:


我正在尝试使用递归函数使用二叉树(不,它不是二叉搜索树,只是二叉树)来制作搜索方法。如果数据在二叉树上,我希望它返回节点,如果不是,我希望它返回一个NULL 值。我已经制作了搜索功能,并且它完美地完成了它的工作。但问题是,该函数似乎不会返回节点。

这是二叉树的struct

struct data
{
    int number;
    struct data *left, *right;
}*root = NULL;

这就是我说的搜索功能:

data* search(struct data *node, int key)
{
    if(node == NULL)
        return NULL;
    else
    {
        printf("\n%d %d -", node->number, key);

        if(node->number== key)
            return node;

        search(node->left, key);
        search(node->right, key);
    }
}

当我像这样调用搜索函数时:search(root, 6);,它说它返回了一个 NULL 值,尽管我已将一个 6 数字推入二叉树(并且搜索函数在return node; 也行,所以我假设该函数返回 NULL。)

我在here 中看到了二叉树的教程,使用并更改了其中的一些代码,但它仍然是一样的。我在这里拼命寻求帮助:(

【问题讨论】:

  • C 还是 C++?完全不同的野兽。
  • 当某些调用返回一个非空指针时,该值会发生什么?
  • @KonradRudolph:实际上是 C,但我使用的是 C++ 编译器,所以,我认为这不会有问题。 .
  • @Jerry Coffin:我不确定我的回答是否正确,但是当它没有返回非空值时,我想将另一个数据推送到树。
  • @aquatorrent 这可能不是问题,但这不是我问的原因。相反,一个好的 C++ 解决方案看起来会完全不同,因此好的建议应该考虑到这一点。

标签: c recursion


【解决方案1】:

您的函数将始终返回NULL,除非顶部节点包含键。您的函数不会对其递归调用的结果做任何事情;事实上,控制流可能会在没有遇到return 语句的情况下“掉线”。

您应该检查递归调用的返回值,并在适当的时候将其传递:

if (node == NULL)
    return NULL;
else if (node->number == key)
    return node;
else {
    data *left = search(node->left, key);
    return left? left: search(node->right, key);
}

注意“三元运算符”(if-then-else 表达式)?:

【讨论】:

  • 对不起,但是-1。当控制在递归调用之后从函数的末尾流出时,你不能依赖它返回 NULL(或其他任何东西)。
  • @JerryCoffin:不会。递归调用的返回值用于return 语句。
  • 它不会跑到最后——它总是返回以下三种情况之一:如果 node == NULL 则返回 NULL,如果 node->number == key 则返回 node,以及 (data* || data*)在第三种情况下。如果第一次搜索返回非 NULL,则使用它的值;如果第二次搜索返回非 NULL,则使用其值;否则,它返回 (data*)(0||0),它恰好为 NULL。
  • @larsmans:我不是在谈论您的函数(这很好),而是您的声明“您的函数将始终返回 NULL ...”在他的函数中,在递归调用之后,控制流结束而不返回任何值。确切的结果是(如果有记忆的话)C 和 C++ 之间的不同,但你当然不能依赖它为 NULL。
  • @JerryCoffin:你是对的,没有发现。现在修好了。
【解决方案2】:

它不会返回搜索到的节点,除非你使用search的返回值

把它改成这样。

data* search(struct data *node, int key)
{
  if(node == NULL)
    return NULL;
  else
  {
    printf("\n%d %d -", node->number, key);

    if(node->number== key)
        return node;
    struct data *tmp;
    tmp = search(node->left, key);
    /* node found ? */
    if (tmp)
        return tmp;
    tmp = search(node->right, key);
    /* node found ? */
    if (tmp)
        return tmp;
  }
  /* search didn't find anything */
  return NULL;
}

【讨论】:

    【解决方案3】:

    您永远不会真正返回递归调用搜索的结果。

    您需要检查这些调用的返回值,如果它们找到该节点,则返回它

    data* search(struct data *node, int key)
    {
        data* found = NULL;
    
        if(node == NULL)
            return NULL;
    
        printf("\n%d %d -", node->number, key);
    
        if(node->number== key)
            return node;
    
        found = search(node->left, key);
        if (found)
            return found;
    
        found = search(node->right, key);
        if (found)
           return found;
    
        return NULL;
    }
    

    【讨论】:

      【解决方案4】:

      有一种更简单、更有效的方法来制作二叉树,那就是简单地使用向量/数组。

      i 是访问向量的 int。向右走,i=i*2。向左走,i=i*2+1。他们永远不会共享同一个地点,并且假设每个地点都将被平均分配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 2013-04-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多