Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中搜索树并输出到该节点的路径+;_C++_Search_Path_Tree - Fatal编程技术网

C++ 在C+中搜索树并输出到该节点的路径+;

C++ 在C+中搜索树并输出到该节点的路径+;,c++,search,path,tree,C++,Search,Path,Tree,假设我们有以下结构: struct ATree { string id; int numof_children; ATree *children[5]; }; 我如何才能搜索id并输出该id的路径?我有办法找到id是否在树中,但输出正确的路径是另一回事。我尝试过使用字符串流,但它似乎不能正常工作(我得到的路径中包含的id没有指向我想要的id)。注意:假设ID在树中只出现一次 这应该使用递归来完成吗?或者可以使用循环来完成吗?对于要通过的每个节点,基本上都应该将从中到达的节点保持为当

假设我们有以下结构:

struct ATree {
  string id;
  int numof_children;
  ATree *children[5];
};
我如何才能搜索id并输出该id的路径?我有办法找到id是否在树中,但输出正确的路径是另一回事。我尝试过使用字符串流,但它似乎不能正常工作(我得到的路径中包含的id没有指向我想要的id)。注意:假设ID在树中只出现一次


这应该使用递归来完成吗?或者可以使用循环来完成吗?

对于要通过的每个节点,基本上都应该将从中到达的节点保持为当前节点。然后只要把它们弹出,找到正确的路径就可以打印出来

如果您将它们保存在
std::stack
结构中,那么当您在到达leaves后返回,并且没有找到所需的
id
时,只需将它们弹出即可


如果以递归方式执行,那么您只需要调用堆栈,这应该足够了,如果您将它们转换为循环(迭代),那么您需要
std::stack
来记住状态,但实际上它相当简单。

您基本上应该保留从中到达当前节点的节点,对于要通过的每个节点。然后只要把它们弹出,找到正确的路径就可以打印出来

如果您将它们保存在
std::stack
结构中,那么当您在到达leaves后返回,并且没有找到所需的
id
时,只需将它们弹出即可


如果以递归方式执行,则只需要调用堆栈,这应该足够了,如果将它们转换为循环(迭代),则需要
std::stack
来记住状态,但实际上相当简单。

算法的大致轮廓:

std::vector< const ATree* >
getPath(const ATree* tree, const std::string& id)
{
        std::vector< const ATree* > path;

        if (tree->id == id) {
                path.push_back(tree);
        } else {
                for (int i=0; i < tree->numof_children; i++) {
                        std::vector< const ATree* > tmp=
                                getPath(tree->children[i], id);
                        if (tmp.size() > 0) {
                            path.push_back(tree);
                            path.insert(path.end(), tmp.begin(), tmp.end());
                                break;
                        }
                }
        }

        return path;
}
std::vector
getPath(常量ATree*树,常量std::string&id)
{
std::vector路径;
如果(树->id==id){
路径。推回(树);
}否则{
对于(int i=0;inumof_children;i++){
标准::向量tmp=
getPath(树->子[i],id);
如果(tmp.size()>0){
路径。推回(树);
insert(path.end(),tmp.begin(),tmp.end());
打破
}
}
}
返回路径;
}

算法的大致轮廓:

std::vector< const ATree* >
getPath(const ATree* tree, const std::string& id)
{
        std::vector< const ATree* > path;

        if (tree->id == id) {
                path.push_back(tree);
        } else {
                for (int i=0; i < tree->numof_children; i++) {
                        std::vector< const ATree* > tmp=
                                getPath(tree->children[i], id);
                        if (tmp.size() > 0) {
                            path.push_back(tree);
                            path.insert(path.end(), tmp.begin(), tmp.end());
                                break;
                        }
                }
        }

        return path;
}
std::vector
getPath(常量ATree*树,常量std::string&id)
{
std::vector路径;
如果(树->id==id){
路径。推回(树);
}否则{
对于(int i=0;inumof_children;i++){
标准::向量tmp=
getPath(树->子[i],id);
如果(tmp.size()>0){
路径。推回(树);
insert(path.end(),tmp.begin(),tmp.end());
打破
}
}
}
返回路径;
}

我相信以下代码为您提供了应该做什么(递归)的概念:

bool-find(常量字符串和i_-id,常量ATree*i_树,字符串和o_路径){
如果(!i_tree)返回false;
如果(i_id==i_树->id){
o_path=i_tree->id;
返回true;
}
字符串路径;
对于(size\u t i=0;inumof\u children;++i){
if(查找(id,i_树->子[i],路径)){
o_path=i_树->id+'/'+路径;
返回true;
}
}
返回false;
}

我相信以下代码为您提供了应该做什么(递归)的概念:

bool-find(常量字符串和i_-id,常量ATree*i_树,字符串和o_路径){
如果(!i_tree)返回false;
如果(i_id==i_树->id){
o_path=i_tree->id;
返回true;
}
字符串路径;
对于(size\u t i=0;inumof\u children;++i){
if(查找(id,i_树->子[i],路径)){
o_path=i_树->id+'/'+路径;
返回true;
}
}
返回false;
}


任何递归都可以用循环重写。我建议将访问过的节点存储在
std::vector
std::list
中,这是您到达节点的路径。@LittledV:这是一个比我以前听过的更有力的说法,如果不在其他地方实现堆栈,我认为这是不正确的。@MooningDuck-Computation 101,任何递归解都可以重写为迭代解。这源于与基本图灵机的等价性。当然,您还需要一些变量。@littleadv:正确,但在许多情况下,迭代必须创建一个堆栈。在这种情况下(如果不考虑stackoverflow),使用递归通常更简单。任何递归都可以用循环重写。我建议将访问的节点存储在
std::vector
std::list
中,这是您到达节点的路径。@LittledV:这是一个比我以前听到的更有力的说法,如果没有在其他地方实现堆栈,我认为这是不正确的。@MooingDuck-Computation 101,任何递归解决方案都可以重写为迭代的。这源于与基本图灵机的等价性。当然,您还需要一些变量。@littleadv:正确,但在许多情况下,迭代必须创建一个堆栈。在这种情况下(如果stackoverflow不是一个问题),使用递归通常更简单。我不能使用堆栈。另一种选择?@DillPixel-那么也许你应该列出你的所有限制,而不是等待解决方案,然后说你不允许使用这个或那个?使用我的解决方案,它不使用堆栈:)@hochi,它实际上。。。它是递归的。好吧,它不使用
std::stack
。我认为这很清楚,因为递归通常使用堆栈。当然,您可以优化尾递归等,但参考