如何搜索链表Graph中两个节点之间的所有路径

时间:2016-11-02 14:01:50

标签: c++

我使用基于邻接的多变量列表列表制作图表。我已经销售了所有创建数据结构的特定功能,但我无法实现在两点之间搜索所有可能的路径((。我想了很多,但无法弄清楚如何获得所有方式,而不仅仅是一个。)我知道我必须使用BFS,但我什么都不能(

   #include <iostream>
    #include <string>


using namespace::std;

typedef string graphElement;

typedef struct vertexTag {
    graphElement data;
    int visited;

    struct edgeTag* edges;

    struct vertexTag* next;
    struct vertexTag* prev;
} vertexT;

typedef struct edgeTag {
    struct vertexTag* connectsTo;
    struct edgeTag* next;
} edgeT;

class graph {
private:
    vertexT* head;
    vertexT* tail;
    vertexT curr;
    int count_vertex;
    queue<vertexT*> queue;

    void BFS(graphElement destenetion, vertexT* startP);
    vertexT* FindVertex(graphElement data);

public:
    graph();
    ~graph();

    vertexT* AddVertex(graphElement data);
    void DeleteVertex(graphElement data);
    edgeT* AddEdge(graphElement source, graphElement destination);
    void DeleteEdge(graphElement source, graphElement destination);

    void PrintGraph();
    void DiskIn();
    void DiskOut();

    void FindAllPaths(graphElement source, graphElement destenetion);
 };

我尝试做的是BFS((。我知道它不太好:(

void graph::FindAllPaths(graphElement source, graphElement destenetion) {
    vertexT *vertP;
    vertexT *startP = NULL;

    for (vertP = head; vertP != NULL; vertP = vertP->next) {
        vertP->visited = 0;
        if (vertP->data == source)
            startP = vertP;
    }
    if (startP == NULL)
    {
        cout << "No such vertex";
        return;
    }
    else
    {
        BFS(destenetion, startP);
    }

}

void graph::BFS(graphElement destenetion, vertexT* startP) {
    vertexT* current;
    edgeT* edgeP;
    vector<string>path;


    queue.push(startP);
    //startP->visited = true;

    while (!queue.empty()) {
        current = queue.front();
        queue.pop();
        if (current->data == destenetion)
            copy(path.begin(), path.end(), ostream_iterator<string>(cout, " "));
        for (edgeP = startP->edges; edgeP != NULL; edgeP = edgeP->next) {
            //if (!edgeP->connectsTo->visited) {
                queue.push(edgeP->connectsTo);
                edgeP->connectsTo->visited = true;
                path.push_back(edgeP->connectsTo->data);
        //  }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

start = Pick any start node
search(start)

function search(node) {
  node.visited = yes
  for each vertex that has an edge to node (call it b): {
    if (b not visited) {
        search(b) // recursive call to search
    }
  }
}

如果您的图形确实包含未通过任何边连接的本地顶点组,则此算法将无法访问所有顶点。在这种情况下,您应该迭代所有节点而不是Pick any start node,而是调用search。无论如何,已经访问过的根节点将被跳过。搜索之后,不要忘记重置所有顶点的visited标志!

修改

正如Михаил所指出的,这只会找到一条路径。要查找所有可能的路径:每次到达目标顶点时,都可以保存路径(可以保留每次递归调用时传递的堆栈,并添加顶点(或边),弹出如下:

start = pick your start vertex
target = pick your target vertex
stack = empty stack
search(start, start, target, stack)
resultingPaths = vector of stacks // here go all possible routes

function search(node, start, target, stack) {
  for each vertex that has an edge to node (call it b): {
    stack.push(b)
    if (b == target) {
      // we have found a path
      resultingPaths.add(a copy of stack)
    } else if (b != start) {
      // keep looking  
      search(b, start, target, stack) // recursive call to search
    }
    stack.pop()
  }
}