在C ++中使用BFS的最短路径

时间:2014-10-16 15:56:41

标签: c++ algorithm graph

我必须编写一个算法来查找未加权图中的最短路径。我发现在未加权图中找到最短路径的最佳方法是简单地执行BFS并在到达目的地后停止。问题是我不知道如何跟踪导致该目的地的路径。

到目前为止,我已经考虑过为每个发现的新节点创建一个新的路径列表,但我无法弄清楚如何实现它。

这个代码似乎在访问每个节点时都有效(它有点乱,对不起):

void shortestPath(string start, string finish, list< list<string> > adjList){

    queue< list< list<vertex*> >::iterator >    myQueue;
    list< list<vertex*> > listVertices = initializeVertices(start, adjList);
    list< list<vertex*> >::iterator aux = extractList(start, listVertices);

    myQueue.push(aux);

    while(myQueue.size() > 0){

        list< list<vertex*> >::iterator vert = myQueue.front();

        for(list<vertex*>::iterator it = vert->begin(); it != vert->end(); it++){
            if((*it)->color == "white"){
                (*it)->color = "gray";
                myQueue.push(extractList((*it)->name, listVertices));
            }

        }

        list<vertex*>::iterator vertAux = vert->begin();
        (*vertAux)->color = "black";
        myQueue.pop();
    }
}

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

您可以通过为每个顶点v保留最短路径树中v的父级的名称来存储最短路径树。然后,您可以通过跟随这些父指针重建所需的最短路径,直到到达源顶点。

答案 1 :(得分:1)

vertex *parent添加到您的顶点类中,然后向您的*vertex函数添加一个输入push并更改此行:

  

myQueue.push(extractList((* it) - &gt; name,listVertices));

到此:

  

myQueue.push(extractList((* it) - &gt; name,listVertices),* vert);

myQueue.pop();检查poped节点是否是您的目的地之后,从while循环中断并从目的地开始并使用循环打印(或您执行的任何操作){{1} }然后node->parent直到你到达来源。

答案 2 :(得分:1)

//Breadth first Search Shortest Path
//It is implemented using Queue Linked list representation
//It is used to pind the shortest path from destination to the source

#include<iostream>
#include<stdio.h>
#include<stdlib.h>

using namespace std;

typedef struct queue1{
    int info;
    struct queue1 *next;
}node;

void createqueue(node **front1,node **rear1){
    *front1=*rear1=NULL;
}

void pushqueue(node **front1, node **rear1,int item){
    node *ptr;
    ptr=(node *)malloc(sizeof(node));
    ptr->info=item;
    ptr->next=NULL;

    if((*front1)==NULL)
        *front1=*rear1=ptr;
    else{
        (*rear1)->next=ptr;
        *rear1=ptr;
    }
}

int popqueue(node **front1){

int item;
    node *ptr;
    ptr=*front1;
    item=ptr->info;
    *front1=ptr->next;

return item;
}

int peekqueue(node *front1){
    return front1->info;
}

bool isEmpty(node *front1){
    if(front1==NULL)
        return true;
return false;
}

int main(){

    int graph[7][7]={
                {0,1,1,0,0,0,0},
                {1,0,0,1,1,0,0},
                {1,0,0,0,0,1,1},
                {0,1,0,0,0,0,0},
                {0,1,0,0,0,0,0},
                {0,0,1,0,0,0,0},
                {0,0,1,0,0,0,0},
             };

    int src;
    cout << "Following is Breadth First Traversal (starting from vertex 0) \n";
    cin>>src;

    int parent[10];
    parent[src]=-1; //Source is the root node

    cout<<"Breadth First Search\n";

node *front1;
node *rear1;
int choice,element,temp;

createqueue(&front1,&rear1);
pushqueue(&front1,&rear1,src);

bool visited[7];

for(int i=0;i<7;i++) //Mark all nodes as visited as false
    visited[i]=false;


    while(!isEmpty(front1)){
        src=popqueue(&front1);
        cout<<src<<"\t";
        if(!visited[src]){
            for(int i=0;i<7;i++){
                if(graph[src][i] && !visited[i]){
                    parent[i]=src;        //TO get the predessecor of the node which will help in backtracking
                    pushqueue(&front1,&rear1,i);
                }
            }
        visited[src]=true;
        }
    }

int destination;
cout<<"\nEnter destination = \n";
cin>>destination;

int j=destination;
cout<<"Path from "<<j<<" to root node is as follows\n";

//Backtrack from destination to root node
do{
    cout<<""<<j<<"\t";
    j=parent[j];
}while(j!=-1);

cout<<"Thank You\n";

return 0;
}