图的表示
这里用结构体来表示图G,和图顶点GraphNode,后面要用到的顶点颜色用枚举类型表示
enum color
{
white = 0,
gray,
black
};
struct graphNode {
char name; //顶点名
struct graphNode *pre; //前驱节点
int d; //深度
color c; //节点颜色
graphNode(char n):name(n),pre(NULL),c(white),d(0) {}
};
struct graph {
vector<graphNode *> v; //顶点集合
map<char, list<graphNode *>> adj; //邻接链表,方便用顶点查找
};
广度优先搜索
伪代码
书上的示例图解
根据书上的伪代码编写广度优先程序
graph BFS(graph G, graphNode *s)
{
s->c = gray;
s->d = 0;
deque<graphNode*> q; //创建一个双端队列
q.push_back(s);
while (!q.empty())
{
graphNode *cur = q.front();
q.pop_front();
char n = cur->name;
for (graphNode *u : G.adj[n]) //遍历当前顶点的邻接链表
{
if (u->c == white) {
u->c = gray;
u->d = cur->d+1; //顶点深度为当前顶点深度加1
u->pre = cur; //前驱为当前顶点
q.push_back(u); //入队
}
}
cur->c = black;
}
return G;
}
图的初始化由上图示例初始:
graph initGraph() {
graph G;
G.v = {new graphNode('r'),new graphNode('v'),new graphNode('s'),new graphNode('w'),
new graphNode('t'),new graphNode('x'),new graphNode('u'),new graphNode('y') };
//初始化邻接链表
G.adj['r'] = { G.v[1],G.v[2] };
G.adj['s'] = { G.v[3],G.v[0] };
G.adj['w'] = { G.v[2],G.v[4],G.v[5] };
G.adj['t'] = { G.v[5],G.v[1],G.v[6] };
G.adj['x'] = { G.v[4],G.v[3],G.v[6],G.v[7] };
G.adj['u'] = { G.v[4],G.v[5],G.v[7] };
G.adj['y'] = { G.v[5],G.v[6] };
G.adj['v'] = { G.v[0]};
return G;
}
调用:
int main()
{
graph G = initGraph();
BFS(G,G.v[2]);
}
打印最短路径
//打印路径
void printPath(graph G, graphNode *s, graphNode *v) {
if (s == v) {
cout << s->name;
}
else if (v->pre == NULL) {
cout << "no path!";
}
else {
printPath(G, s, v->pre);
cout << v->name;
}
}
调用:
int main()
{
graph G = initGraph();
G=BFS(G,G.v[2]);
printPath(G, G.v[2], G.v[6]);
}
输出:
swtu