【问题标题】:What are some best practices for searching a binary tree?搜索二叉树的最佳实践是什么?
【发布时间】:2020-12-15 20:01:30
【问题描述】:

我正在学习 C 中的二叉树,我编写了一个函数来搜索我的树,它是一棵字符串树。但是,它可以工作,如果字符串不在树中,它会出现故障,我正在努力弄清楚如何对其进行错误检查。我想知道是否有任何搜索树的最佳实践。

tnode *search(tnode *p, char *w)
{
    if (p->word == NULL || strcmp(w, p->word) == 0)
        return p;
    else if (strcmp(w, p->word) < 0)
        return search(p->left, w);
    else
        return search(p->right, w);
}

我已经改变了这个函数,但只要它返回NULL,它就会出错。我能想到的最好的解决方案是让它返回一个intboolchar *,这样我就不必处理返回一个NULL 结构。

有没有办法让它与这个函数一起工作,还是让它不返回一个结构更好?

【问题讨论】:

  • 什么是p-&gt;leftp-&gt;right 是NULL?这可能意味着该值不在树中。或者检查p 本身是否为NULL。
  • 当有简单的迭代解决方案时,最好不要使用递归函数。只要p不为空,如果p-&gt;word匹配,则返回p,否则根据比较将p设置为p-&gt;leftp-&gt;right,并重复。循环结束后,返回NULL

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


【解决方案1】:

并非每个节点都有左子节点和右子节点。有些人两者都没有,有些人有一个或另一个。因此,如果要搜索的值不在树中,代码最终将调用search(NULL, w)。这是未处理的。

可以进行其他改进:

  • 有人可能想尝试搜索一棵空树 (p == NULL),所以应该检查一下。我们将利用相同的检查来解决主要问题。
  • 拥有一个具有NULL 值的节点(p-&gt;word)是没有意义的,因此检查它没有意义。
  • 搜索NULL 也没有意义。我们也可以避免这种检查。
  • 让我们避免两次调用strcmp
  • 让我们将字符串标记为常量。
tnode *search(tnode *p, const char *w) {
    if (p == NULL)
        return NULL;

    int cmp = strcmp(w, p->word);
    if      (cmp < 0) return search(p->left, w);
    else if (cmp > 0) return search(p->right, w);
    else              return p;
}

最后,这里没有理由使用递归。

tnode *search(tnode *p, const char *w) {
    while (p != NULL) {
        int cmp = strcmp(w, p->word);
        if      (cmp < 0) p = p->left;
        else if (cmp > 0) p = p->right;
        else              return p;
    }

    return NULL;
}

【讨论】:

    【解决方案2】:

    我想说只有一个 p 等于 Null 缺失的守卫。

    tnode*
    search(tnode *p, char *w)
    {
        if(p == NULL || w == NULL) return NULL;
    
        if (strcmp(w, p->word) == 0)
            return p;
        else if (strcmp(w, p->word) < 0)
            return search(p->left, w);
        else
            return search(p->right, w);
    }
    
    

    然后调用函数必须检查 search() 是否返回 Null(未找到)或指针(节点)。

    出现分段错误的原因是,如果键不在树中,则调用 search() 时返回 Null。 search() 所做的第一件事是使用 p->word 检索单词,但 p 不是有效地址,导致异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多