我想大部分读者都用Floyd或者Dijstra算法,甚至dfs算过最短路吧。
其实BFS也可以计算最短路。(补充:本文只针对无权图,有权图很难用BFS)
当我们用BFS找端对端最短路时,从出发点开始,第一次遍历到终点时过的那条路径就是最短的路径。(读者可以思考一下为什么!)
下面就用邻接表来实现一下BFS最短路,并把路径打出来。
#include<iostream>
#include<fstream>
#include<queue>
using namespace std;
const int MAX = 50;
struct link
{
int data;
link *next;
};
struct Node
{
int v; //顶点相关的信息
link *next;
};
struct Graph
{
Node node[MAX+1]; //所有的结点
int nodeCnt; //用来记录图中结点的数目,这里假设用的是连通图。假设不连通,稍微改一下本程序就行了,具体操作留给读者思考!
};
int visited[MAX+1]; //标志数组
int pa[MAX+1];
/* 读取文件中的数据,构造一个邻接表来表示图 */
Graph readGraph()
{
ifstream cin("c:\\graph.txt");
//表的初始化
Graph graph;
int i ;
for(i = 1; i < MAX; i ++)
{
graph.node[i].v = i;
graph.node[i].next = NULL;
}
int n1 = 0,n2 = 0;
link *s;
graph.nodeCnt = 1;//把结点数初始化为1
while(cin>>n1>>n2)
{
if(graph.nodeCnt < n1) graph.nodeCnt=n1;
if(graph.nodeCnt < n2) graph.nodeCnt=n2;
s = new link;
s->data = n2;
s->next=graph.node[n1].next;
graph.node[n1].next=s; //从尾部插入
//delete(s);
s=new link;
s->data = n1;
s->next=graph.node[n2].next;
graph.node[n2].next=s; //反过来也赋值,说明本程序测试的是无向图,如果是有向图的话读者应该知道怎么改了吧!
//delete(s);
}
return graph;
}
/* 打印邻接表 */
void printGraph(Graph graph)
{
link *p;
for(int i = 1; i <= graph.nodeCnt; i ++)
{
cout<<graph.node[i].v<<" -- ";
p=graph.node[i].next;
while(p!=NULL)
{
cout<<p->data;
p=p->next;
if(p != NULL)
cout<<",";
}
cout<<endl;
}
}
/* 用BFS求最短路径 */
void shortestPath(Graph graph, int s, int d)
{
cout<<"从"<<s<<"到"<<d<<"的bfs最短路求解过程如下:"<<endl;
queue<int> que ;
link * p = NULL;
//int cnt = 0;
int parents = s;
memset(visited,0,sizeof(visited));
memset(pa,0,sizeof(pa));
visited[s] = 1;
pa[s] = -1;
que.push(s);
while(!que.empty()){
p = graph.node[que.front()].next;
parents = que.front();
que.pop();
//cnt ++;
while(p != NULL)
{
if(!visited[p->data])
{
visited[p->data] = 1;
pa[p->data] = parents;
cout<<"访问:"<<p->data<<endl;
if(p->data == d) //找到了目标结点
{
//cout<<"在第"<<cnt<<"层找到目标结点!(出发点算第一层)"<<endl;
break;
}
que.push(p->data);
}
p = p->next;
}
}
cout<<"路径如下:"<<endl;
parents = d;
//cout<<parents<<" <- ";
while(pa[parents] != -1)
{
cout<<parents<<" <- ";
parents = pa[parents];
}
cout<<parents<<endl;
}
int main()
{
int s,d;
Graph graph = readGraph();
printGraph(graph);
while(true)
{
cout<<"请输入起点和终点:"<<endl;
cin>>s>>d;
shortestPath(graph, s , d);
}
return 0;
}
输入文件graph.txt里数据格式如下:
1 2 1 3 1 4 2 4