C++ 如何在二叉树中使用顺序遍历查找节点?

C++ 如何在二叉树中使用顺序遍历查找节点?,c++,C++,我需要在二叉树中找到值为n的节点并返回它的链接。我只能用顺序遍历找到它。为什么?因为这是个骗人的问题 我感到困惑,因为我认为实现有序遍历的唯一方法是使用递归。因此,递归自动为基本条件提供一个return语句,但我们也希望返回找到的节点。因此,这需要另一个return语句,这可能会让人困惑 节点定义: struct node { int item; node* l; // Link to left child node* r; // Link to right child

我需要在二叉树中找到值为n的节点并返回它的链接。我只能用顺序遍历找到它。为什么?因为这是个骗人的问题

我感到困惑,因为我认为实现有序遍历的唯一方法是使用递归。因此,递归自动为基本条件提供一个return语句,但我们也希望返回找到的节点。因此,这需要另一个return语句,这可能会让人困惑

节点定义:

struct node {
    int item;
    node* l; // Link to left child
    node* r; // Link to right child
};
typedef node* link;
我的尝试:

link find(link x,int n) {
    if (x == 0) return; // Base condition for recursion
    find(x->l,n);
    if (x->item == n) return x;
    find(x->r,n);
}

如果树中不存在给定节点,如何返回null?

如果找到链接,则需要将链接传播回:

link find(link x,int n) {
    if (x == 0) return 0; // Base condition for recursion
    link r = find(x->l,n);
    if(r != 0) {
        return r;
    }
    if (x->item == n) return x;
    return find(x->r,n);
}
因此,在您访问了左边的子级之后,如果该子级返回了一个真实的
链接,则向上传播该链接,否则,继续搜索。对正确的子项也是如此,尽管您可以简单地返回正确的子项、结果,因为如果它是
0
,您仍然需要返回
0

或未优化的变体:

link find(link x,int n) {
    if (x == 0) return 0; //we read below a leave, that's not gonna work
    link r = find(x->l,n); //attempt a search on the left child
    if(r != 0) { //we found it!
        return r; //now return what we've found
    }//apparently it's not in the left child, now continue
    if (x->item == n) return x; //hmm, maybe we should check or own value, if it is equal, we report ourself
    //apparently that failed as well, last chance: the right child
    r = find(x->r,n); //attempt a search on the right child
    if(r != 0) { //we found it!
        return r; //now return what we've found
    }//apparently it's not in the right child either
    return 0;//we didn't find anything, so let's return 0
}
但是最后一个
if
部分可以优化,因为模式:

if(x != a) {
    return x;
}
return a;
(具有任意
x
a


是一种没有多大意义的模式。毕竟,如果
x==a
,我们在这两种情况下都返回
a

如果找到链接,您需要将链接传播回:

link find(link x,int n) {
    if (x == 0) return 0; // Base condition for recursion
    link r = find(x->l,n);
    if(r != 0) {
        return r;
    }
    if (x->item == n) return x;
    return find(x->r,n);
}
因此,在您访问了左边的子级之后,如果该子级返回了一个真实的
链接,则向上传播该链接,否则,继续搜索。对正确的子项也是如此,尽管您可以简单地返回正确的子项、结果,因为如果它是
0
,您仍然需要返回
0

或未优化的变体:

link find(link x,int n) {
    if (x == 0) return 0; //we read below a leave, that's not gonna work
    link r = find(x->l,n); //attempt a search on the left child
    if(r != 0) { //we found it!
        return r; //now return what we've found
    }//apparently it's not in the left child, now continue
    if (x->item == n) return x; //hmm, maybe we should check or own value, if it is equal, we report ourself
    //apparently that failed as well, last chance: the right child
    r = find(x->r,n); //attempt a search on the right child
    if(r != 0) { //we found it!
        return r; //now return what we've found
    }//apparently it's not in the right child either
    return 0;//we didn't find anything, so let's return 0
}
但是最后一个
if
部分可以优化,因为模式:

if(x != a) {
    return x;
}
return a;
(具有任意
x
a


是一种没有多大意义的模式。毕竟,如果
x==a
,我们在这两种情况下都返回
a

“我不确定这是否符合我们的要求。”那么您实际测试了它吗?另外,请明确你想做什么。我的意思是,它显然是不完整的。我的意思是,如果节点不存在怎么办?还有什么是
link
please?对不起,我的修复球坏了,我今天的日子不好过:-……这是一个编译错误,因为基本条件返回必须返回一个值。@ HealthBoy请添加必要的信息。也考虑给A,这可以很容易地被任何读者复制。“我不确定这是否符合我们所希望的。”那么你真的测试了吗?请明确你想做什么。我的意思是,它显然不完整。我的意思是,如果节点不存在怎么办?还有什么
link
请?对不起,我的水晶球要修理了,我今天过得不好:-(……这是编译错误,因为基本条件返回必须返回一个值。@ HeadBoad请添加必要的信息。也考虑给出A,这可以很容易地被任何读者复制。为什么您处理了<代码>查找(X-> L,N)< /代码>和<代码>查找(X-> R,N)。
不同?@BloodBrother:请看代码片段下面的注释。你可以同样对待它,但这是一个优化。如果所有操作都失败了,你无论如何都需要返回
0
。但是如果正确的孩子失败了,它也会返回
0
。。我很抱歉让人讨厌,但我没有遵守。你能发布这个unoptim吗请在下面添加代码,以便我能看到差异。请?@BloodBrother:添加了一些评论故事。我喜欢你阅读评论的乐趣。:)你为什么要处理
find(x->l,n)
find(x->r,n)
不同?@BloodBrother:请看代码片段下面的注释。你可以同样对待它,但这是一个优化。如果所有操作都失败了,你无论如何都需要返回
0
。但是如果正确的孩子失败了,它也会返回
0
。。我很抱歉让人讨厌,但我没有遵守。你能发布这个unoptim吗请在它的正下方添加代码,以便我能看到差异。请?@BloodBrother:添加了一些评论故事。我喜欢你让阅读评论变得有趣的方式。:)