C中的递归和树搜索?

C中的递归和树搜索?,c,tree,binary-tree,callstack,C,Tree,Binary Tree,Callstack,对树和递归函数来说有点陌生 我知道如何创建堆栈和如何创建递归函数的基础知识 我正在进行一个预先排序的遍历搜索,当搜索的值与某个节点的值匹配时,该搜索应该返回树中某个节点的地址 我在返回部分遇到了问题…我试着阅读调用堆栈上的一些内容…但我不知道如何实现它。它已经在那里了还是我必须做这个堆栈?如果我必须做这个堆栈,我该如何做呢?我读到它需要与树的高度成比例。。。找到树的高度的最好方法是做另一个函数吗 以下是我迄今为止编写的一些代码: Tree和NodePtr是指向节点的指针 NodePtr Sear

对树和递归函数来说有点陌生

我知道如何创建堆栈和如何创建递归函数的基础知识

我正在进行一个预先排序的遍历搜索,当搜索的值与某个节点的值匹配时,该搜索应该返回树中某个节点的地址

我在返回部分遇到了问题…我试着阅读调用堆栈上的一些内容…但我不知道如何实现它。它已经在那里了还是我必须做这个堆栈?如果我必须做这个堆栈,我该如何做呢?我读到它需要与树的高度成比例。。。找到树的高度的最好方法是做另一个函数吗

以下是我迄今为止编写的一些代码: Tree和NodePtr是指向节点的指针

NodePtr SearchTree(int v, Tree T)
{
    //printf(" %i \n", T->value);

    if(T->value == v) 
    {
        return T;
    }
    else
    {
        if(T->Left != NULL) SearchTree(value, T->Left);
        if(T->Right != NULL) SearchTree(value, T->Right);
    }

    return NULL;
}
首先

现在,您想返回递归调用
SearchTree()
返回的内容,因为您使用递归将问题委托给您自己的两个实例,因此如果您没有得到上游的返回值,任何事情都不可能起作用:

NodePtr SearchTree(int v, Tree t)
{
    printf(" %i \n", t->value);
    if (t->value == v) {
        return t;
    } else {
        if (t->Left != NULL) {
            NodePtr left = SearchTree(v, t->Left);
            if (left != NULL) {
                return left;
            }
        }
        if (t->Right != NULL) {
            return SearchTree(v, t->Right);
        }
    }

    return NULL;
}

您不需要担心调用堆栈;它的工作原理是由C编译器隐藏的,除非您正在搜索非常深的树,否则它不会打扰您

您的算法或多或少是正确的,但在访问另一个子树之前,需要检查递归调用返回的值是否为null。比如:

    if(T->Left != NULL) { NodePtr temp=SearchTree(value, T->Left); 
                          if (temp !=NULL)  return temp; 
                        } 
    if(T->Right != NULL) return SearchTree(value, T->Right); 

您不需要自己创建调用堆栈。它是由执行程序的运行时环境(如操作系统或java虚拟机,如果您使用java)维护的数据结构。无论何时调用函数,都会将其参数和局部变量推送到堆栈上。当函数存在时,它们将弹出


作为一名程序员,您通常不必担心它。了解调用堆栈有助于准确理解递归函数调用(或任何函数调用)期间发生的情况,或者了解局部变量的来源或函数退出后发生的情况。

Ira Baxter答案和Frédéric Hamidi答案中的所有特殊情况都表明设计不太正确:

NodePtr SearchTree(int v, NodePtr T)
{
    if (T == NULL || T->value == v)
        return T;
    NodePtr R = SearchTree(v, T->Left);
    if (R == NULL)
        R = SearchTree(v, T->Right);
    return R;
}
我恭敬地说,这更简单。诚然,在处理空叶节点时,它会再进行一次函数调用,但“if NULL”测试很少


另外,我认为函数的参数(在原始版本中名义上是一棵树)与NodePtr的类型相同,因此我选择只使用NodePtr而不使用Tree。树由NodePtr表示,NodePtr是树的根节点。

如果左子树为非空,并且搜索无法在其中找到值,则不会在右子树中查找。有时它找不到正确的节点。@Ira,是的,我也看到了,但是错误在发问者的代码中。。。我们应该解决他所有的问题还是回答他的问题答案是预先更新的。没错,你不能回答所有隐含的问题或解决所有未说明的问题。但是对于递归,人们通常需要在基本情况、递归和处理递归调用的响应方面得到帮助。@Ira,我明白你的意思,这在我们的情况下是有效的。谢谢:)