for递归函数中的循环在递归结束后继续

时间:2017-04-05 16:00:24

标签: c++ algorithm recursion graph

我正在使用C ++在图表上实现深度优先搜索。给定起始顶点,算法应执行DFS直到找到目标节点(即<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"> <property name="soapVersion"> <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11" /> </property> <property name="messageProperties"> <util:map> <entry key="javax.xml.soap.write-xml-declaration" value="true"/> </util:map> </property> </bean> 设置为true的节点),并返回所采用的路径。我试图递归地执行此操作,这是我的代码:

goal

我知道生成的路径将按照DFS访问它们的顺序列出节点,而不是从开始到目标节点的实际路径。

问题是即使找到目标节点,该功能也会继续打印节点。为避免这种情况,我使用vector<char>* dfs(graph g, node* s){ static vector<char> path; s->set_visited(); path.push_back(s->get_tag()); //Adds node to path if(s->is_goal()){ g.set_all_visited(); } else{ for(int i=0; i<(s->get_no_edges()); i++){ if(!(s->get_edge(i)->get_dest()->is_visited())) //If it is unvisited, apply recursion dfs(g, s->get_edge(i)->get_dest()); } } return &path; } 将图g中的所有节点设置为已访问,并在set_all_visited()部分中检查是否已访问某个节点,然后继续操作,但这似乎不合适工作。当我执行空运行时,即使在找到目标节点之后,该函数仍继续访问else循环中节点的所有边缘,并且我不知道如何阻止这种情况发生。

2 个答案:

答案 0 :(得分:1)

您按价值而不是按参考传递g。这意味着无论何时找到目标节点并从递归调用返回,g的实例仍将其节点设置为未访问。这就是重复发生的原因。

答案 1 :(得分:1)

我知道您的主要问题已得到解答,但我仍然会提出一些建议:

1)不要使用静态向量,你不能重用该函数。您可以创建一个向量,在该向量中,您期望路径并将指针传递给向量。

2)为了确保您没有路径中的所有访问过的节点,您可以从dfs函数返回一个bool来表示是否有到目的地的路径。您也可以避免以这种方式传递图形对象。

通过这些更改,您的代码将变为:

bool dfs(node* s, vector<char>* path){

    s->set_visited();

    if(s->is_goal()){
        path.push_back(s->get_tag());
        return true;
    }

    else{
        for(int i=0; i<(s->get_no_edges()); i++){
            if(!(s->get_edge(i)->get_dest()->is_visited())) //If it is unvisited, apply recursion
                if(dfs(s->get_edge(i)->get_dest(), path)) {
                    path.push_back(s->get_tag());
                    return true;
                }
        }
    }

    return false;
}

这将返回反向路径,即从目的地到源的路径,有std :: reverse。

如果您使用BFS,假设边缘重量相等,您将获得最短路径而不是某些随机路径。