【问题标题】:How to use recursion to determine if path exists between two nodes in graph?如何使用递归来确定图中两个节点之间是否存在路径?
【发布时间】:2017-10-17 14:55:40
【问题描述】:

我正在尝试实现一个函数pathExists,它以图形 ADT 'g' 作为输入,以及两个顶点 ab。如果两个顶点之间存在路径,则该函数返回 1,否则返回 0。我不确定如何执行此操作。我在下面实现了深度优先搜索(DFS)算法,它将生成int *visited,一个包含访问节点顺序的数组。我只是想知道如何使用这个算法来实际编写pathExists 函数。谢谢!

编辑:尝试-

void dfsR(Graph g, int v); 
int *visited;  // array of visited
int order; 


int PathExists(Graph g, int src, int dest)
{

    int i;
    order = 1; 
    visited = malloc(sizeof(int)*g->nV); 

    for(i=0; i<g->nV; i++){
        visited[i] = -1; 
    }

    dfsR(g, src);
    int connected = 0; 


    if(visited[dest]!=-1){
        connected = 1;
    }


   return connected;
}

void dfsR(Graph g, int v){ 

    visited[v] = order++; 
    int w; 
    for(w=0; w<g->nV; w++){
        if(!hasEdge(g, v,w)){
            continue; 
        }
        if(!visited[w]){
            dfsR(g, w); 
        }
    }

}

【问题讨论】:

  • 假设您从两个节点之一开始执行深度优先搜索。当且仅当且仅在该搜索期间访问了另一个时,它们之间存在一条路径。
  • @JohnBollinger 你从哪个节点开始有关系吗?一个必须小于另一个吗?
  • 因为这是目前写的,我想你不能说。您将visited[v] 设置为DFS 访问顶点v 的顺序,但您仅malloc 该数组,您从不初始化它的值。它包含任意数据并且很可能包含序列1, 2, ..., nV(g),这可能使它看起来好像一个完全未连接的图是完全连接的。如果visited[k] &lt;= nV(g),则无法知道它是由 DFS 设置的,还是在分配时恰好具有该值。
  • @Patrick87 那么应该将所有内容初始化为什么? -1 也许?
  • @novice 可以。 0 也应该工作。基本上,只要保证不在1, 2, ..., nV(g) 范围内,任何事情都会起作用。

标签: c algorithm graph-theory graph-traversal


【解决方案1】:

我会建议这个更快的解决方案。 第一个提示是,如果您已经访问过目标节点,或者您离它只有一跳,请避免浪费时间。第二个提示是尽可能少地使用全局变量(作为一般规则)。因此,我提出的解决方案如下:

typedef unsigned char bool;
#define true  1
#define false 0

bool dfsR(Graph g, int v, int dest, bool * visited);

bool PathExists(Graph g, int src, int dest)
{
    bool connected = false;  // result
    bool * visited = 0;  // array of visited nodes

    if (src == dest) {
        return true;
    }

    // initialize the support array
    visited = malloc(g->nV);
    memset(visited, false, g->nV);

    // call the recursive depth first search
    connected = dfsR(g, src, dest, visited);

    // free the memory from the support array
    free(visited);

    return connected;
}

bool dfsR(Graph g, int v, int dest, bool * visited){ 
    visited[v] = 1;

    // check if there is a direct edge toward dest before going on with the recursion
    if (hasEdge(g, v, dest)) {
        return true;
    }
    // try to find it recursively
    bool connected;
    for(int w=0; w<g->nV; w++) {
        if(hasEdge(g, v, w) && !visited[w]) {
            if (dfsR(g, w, dest, visited)) {
                return true;
            }
        }
    }
    return false;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2021-03-04
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多