我们已经学习过了图的广度优先遍历,广度优先遍历的应用之一就是去求单源最短路径问题,即从图中的某结点出发,到其余节点的路径长度(经过的边数)。
算法核心:
void BFSDistance(GraAdList G, int v) {
int front, rear, j;
int queue[MAX];
front = rear = -1;
EdgeNode* p;
visited[v] = 1;
D[v] = 0;
queue[++rear] = v;
while (front != rear) {
v = queue[++front];
p = G.AdList[v].first;
while (p)
{
j = p->adjvex;
if (visited[j] == 0)
{
D[j] = D[v] + 1;
visited[j] = 1;
queue[++rear] = j;
}
p = p->next;
}
}
}
完整代码:
#include<iostream>
using namespace std;
#define MAX 6
int visited[MAX];
int D[MAX] = { 9999 };
typedef struct EdgeNode {
int adjvex;
EdgeNode* next;
};
typedef struct VexNode {
char data;
EdgeNode* first;
};
typedef struct GraAdList {
VexNode AdList[MAX];
int vexnum;
int edgenum;
};
//创建邻接矩
void Creat(GraAdList& G) {
int i, j, k;
EdgeNode* e = NULL;
EdgeNode* q = NULL;
cout << "请输入顶点数和边数: " << endl;
cin >> G.vexnum >> G.edgenum;
cout << "请输入顶点信息" << endl;
for (k = 0; k < G.vexnum; k++)
{
cin >> G.AdList[k].data;
G.AdList[k].first = NULL;
}
for (k = 0; k < G.edgenum; k++)
{
cout << "请输入边(vi,vj)的下标i,j: " << endl;
cin >> i >> j;
e = new EdgeNode;
e->adjvex = j;
e->next = G.AdList[i].first;
G.AdList[i].first = e;
}
}
void myprint(GraAdList G) {
cout << endl << "邻接表: " << endl;
EdgeNode* p;
for (int i = 0; i < G.vexnum; i++)
{
cout << G.AdList[i].data << ": ";
for (p = G.AdList[i].first; p; p = p->next)
{
cout << p->adjvex << " ";
}
cout << endl;
}
}
void BFSDistance(GraAdList G, int v) {
int front, rear, j;
int queue[MAX];
front = rear = -1;
EdgeNode* p;
visited[v] = 1;
D[v] = 0;
queue[++rear] = v;
while (front != rear) {
v = queue[++front];
p = G.AdList[v].first;
while (p)
{
j = p->adjvex;
if (visited[j] == 0)
{
D[j] = D[v] + 1;
visited[j] = 1;
queue[++rear] = j;
}
p = p->next;
}
}
}
int main() {
GraAdList G;
Creat(G);
myprint(G);
for (int i = 0; i < G.vexnum; i++)
{
visited[i] = 0;
}
cout << endl << "广度有限遍历: " << endl;
BFSDistance(G, 0);
for (int i = 0; i < G.vexnum; i++)
{
cout << D[i] << " ";
}
return 0;
}
执行结果:
我创建的图: