C++ C+中的DFS+;:如果节点包含搜索的键,则返回该节点

C++ C+中的DFS+;:如果节点包含搜索的键,则返回该节点,c++,algorithm,tree,depth-first-search,C++,Algorithm,Tree,Depth First Search,我的程序目标是使用深度优先搜索搜索具有给定键的树节点,如果找到具有该键的节点,它将返回给调用者函数。问题是,在DFS执行后访问节点会导致程序因分段错误而终止,而这恰恰是在右子树中搜索节点时,而不是在左子树上搜索节点时 这是源代码: #include <iostream> using namespace std; struct node char data; struct node *left; struct node *right; }; struct

我的程序目标是使用深度优先搜索搜索具有给定键的树节点,如果找到具有该键的节点,它将返回给调用者函数。问题是,在DFS执行后访问节点会导致程序因分段错误而终止,而这恰恰是在右子树中搜索节点时,而不是在左子树上搜索节点时

这是源代码:

#include <iostream>

using namespace std;

struct node 
    char data;
    struct node *left;
    struct node *right;
};

struct node *root = nullptr;

struct node* addNewNode(char newData) {
    struct node* newNode = new node;
    newNode->data = newData;
    newNode->left = nullptr;
    newNode->right = nullptr;

    return newNode;
}

struct node* preOrder(struct node *srcNode, char key) {
    if (srcNode != nullptr) {
        if (srcNode->data == key)
            return srcNode;
        return preOrder(srcNode->left, key);
        return preOrder(srcNode->right, key);
    }
}

int main() {
    root = addNewNode('a');
    root->left = addNewNode('e');
    root->right = addNewNode('c');
    root->left->left = addNewNode('h');
    root->left->right = addNewNode('z');

    struct node* res = preOrder(root, 'c');    
    cout << res->data;

    return 0;
}
#包括
使用名称空间std;
结构节点
字符数据;
结构节点*左;
结构节点*右;
};
结构节点*root=nullptr;
结构节点*addNewNode(char newData){
结构节点*newNode=新节点;
newNode->data=newData;
newNode->left=nullptr;
newNode->right=nullptr;
返回newNode;
}
结构节点*预排序(结构节点*srcNode,字符键){
if(srcNode!=nullptr){
if(srcNode->data==键)
返回src节点;
返回预订单(srcNode->left,key);
返回预订单(srcNode->right,key);
}
}
int main(){
root=addNewNode('a');
root->left=addNewNode('e');
root->right=addNewNode('c');
root->left->left=addNewNode('h');
root->left->right=addNewNode('z');
结构节点*res=preOrder(根,'c');
cout数据;
返回0;
}

您的
预订单
函数并不总是返回值。如果
srcNode
nullptr
,则应返回
nullptr

您的编译器应该警告您这一点!如果不是,请更改编译器设置,或使用更好的编译器

编辑:同时-在尝试使用之前,您应该检查
res
是否为
nullptr

编辑2:我没看到这一点

    return preOrder(srcNode->left, key);
    return preOrder(srcNode->right, key);

对preOrder的第二个调用将永远不会被调用(因为您已经返回),因此您永远不会搜索右侧节点。您需要更改逻辑,以便在左侧搜索返回null ptr时,它在右侧节点上搜索。

您的
preOrder
函数并不总是返回值。如果
srcNode
nullptr
,则应返回
nullptr

您的编译器应该警告您这一点!如果不是,请更改编译器设置,或使用更好的编译器

编辑:同时-在尝试使用之前,您应该检查
res
是否为
nullptr

编辑2:我没看到这一点

    return preOrder(srcNode->left, key);
    return preOrder(srcNode->right, key);

对preOrder的第二个调用将永远不会被调用(因为您已经返回),因此您永远不会搜索右侧节点。您需要更改逻辑,以便在左侧搜索返回null ptr时在右侧节点上搜索。

好的,右子树上的第二个前序永远不会被调用是有意义的,但是在哪里检查左子树是否返回null ptr?与其立即返回左子树的结果,不如将其存储在局部变量中。然后,如果变量不是
nullptr
,则返回它,否则像现在这样检查正确的子树。我认为查找节点的更简单方法是使用node*(例如res)类型的全局变量,如果(srcNode->data==key)那么res=srcNode。然后,不需要返回预排序调用。但这也意味着,如果找到了节点,您将继续查找树中的所有其余节点。此外,使用全局变量会使在较大的程序(特别是多线程程序)中使用此函数变得更加困难。对于这个项目来说,这可能不是现在或将来的问题,但这是一个很好的实践。黑暗势力,非常感谢你们的时间和帮助!好的,右子树上的第二个前序永远不会被调用是有意义的,但是在哪里检查左子树是否返回了null ptr?与其立即返回左子树的结果,不如将其存储在局部变量中。然后,如果变量不是
nullptr
,则返回它,否则像现在这样检查正确的子树。我认为查找节点的更简单方法是使用node*(例如res)类型的全局变量,如果(srcNode->data==key)那么res=srcNode。然后,不需要返回预排序调用。但这也意味着,如果找到了节点,您将继续查找树中的所有其余节点。此外,使用全局变量会使在较大的程序(特别是多线程程序)中使用此函数变得更加困难。对于这个项目来说,这可能不是现在或将来的问题,但这是一个很好的实践。黑暗势力,非常感谢你们的时间和帮助!