// 图的广度优先遍历算法BFS
// 1、存储结构:临界表(选用这个) + 临界矩阵
// 2、遍历算法:BFS(选这个)+ DFS
// 临界表
// 结点方式:a.头结点 + b.边表结点
// a.头结点----data(数据) | firstedge(第一条边)
// b.边表结点----adjvex(临界点域:存放与该点相临的结点在数组中的位置) | nextarc(链域:指向下一条边或弧)
// BFS
// 1、创建visited数组,记录该结点是否被访问过
// 2、创建队列
// a.将第一个结点入队
// b.将该结点相邻的结点
// c.将第一个结点出对
#include <string>
#include <iostream>
#define MAXNUM 100 // 图中最大顶点数
using namespace std;
typedef string VexType; // 结点类型
typedef VexType QElemType;
struct ArcNode;
// a.头结点
struct HNode
{
VexType data;
ArcNode *firstedge;
};
// b.边表结点
struct ArcNode
{
int adjvex;
ArcNode *nextarc;
};
typedef HNode AdjList[MAXNUM]; // 头结点数组 AdjList v; ---- HNode v[MVNUM];
// 图的结构定义
struct ALGraph
{
AdjList vertices; // vertices -- vertex的复数,找到头结点相当于找到了邻接表
int vexnum, arcnum; // 图当前顶点数和弧数
bool visited[MAXNUM]; // 1
};
// 采用临界表的方式创建无向图
void CreateUDG(ALGraph &);
// 定位临界表中点的信息
int LocateVex(const ALGraph &, VexType &);
// BFS
void BFS(ALGraph &);
// 创建队列
struct Queue
{
QElemType elem[MAXNUM];
int front, rear;
};
void InitQueue(Queue &Q); // 初始化
bool IsEmptyQueue(const Queue &Q); // 判断是否为空
void EnQueue(Queue &Q, QElemType &v); // 入队
QElemType DeQueue(Queue &Q); // 出对
int main()
{
ALGraph G;
CreateUDG(G);
for (int i = 0; i < G.vexnum; ++i)
{
cout << G.vertices[i].data << " ";
cout << "该结点相邻的边: ";
ArcNode *temp = G.vertices[i].firstedge;
while (temp)
{
cout << G.vertices[temp->adjvex].data << " ";
temp = temp->nextarc;
}
cout << endl;
}
// // 测试队列
// QElemType e = "v1";
// Queue q;
// EnQueue(q, e);
// cout << DeQueue(q) << endl;
BFS(G);
return 0;
}
void CreateUDG(ALGraph &G)
{
// 1.建立头结点数组
cout << "请输入结点数和边数: " << endl;
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; ++i)
{
cout << "请输入第" << i + 1 << "个结点信息:" << endl;
cin >> G.vertices[i].data;
G.vertices[i].firstedge = NULL;
}
// 2.建立结点相邻的结点信息
// a.定位结点在结点表中的位置;
// b.生成两个边表结点头插到头结点后面
for (int i = 0; i < G.arcnum; ++i)
{
cout << "请输入第" << i + 1 << "条边所依赖的结点: " << endl;
VexType v1, v2;
cin >> v1 >> v2;
// a
int i1 = LocateVex(G, v1);
int i2 = LocateVex(G, v2);
// b
ArcNode *p1 = new ArcNode{i1, NULL};
p1->nextarc = G.vertices[i2].firstedge;
G.vertices[i2].firstedge = p1;
ArcNode *p2 = new ArcNode{i2, NULL};
p2->nextarc = G.vertices[i1].firstedge;
G.vertices[i1].firstedge = p2;
}
// 初始化visited数组
for (int i = 0; i < G.vexnum; ++i)
{
G.visited[i] = 0;
}
}
int LocateVex(const ALGraph &G, VexType &v)
{
for (int i = 0; i < G.vexnum; ++i)
{
if (v == G.vertices[i].data)
return i;
}
return -1;
}
void BFS(ALGraph &G)
{
Queue q;
InitQueue(q);
cout << "选择一个遍历起点: ";
VexType e;
cin >> e;
EnQueue(q, e);
int j = LocateVex(G, e);
G.visited[j] = 1;
while (!IsEmptyQueue(q))
{
e = DeQueue(q);
cout << "出对: " << e << endl;
int i = LocateVex(G, e);
ArcNode *temp = G.vertices[i].firstedge;
while (temp)
{
if (!G.visited[temp->adjvex])
{
VexType e1 = G.vertices[temp->adjvex].data; // 入队元素
// cout << "入队: " << e1 << endl;
EnQueue(q, e1);
G.visited[temp->adjvex] = 1;
}
temp = temp->nextarc;
}
}
}
void InitQueue(Queue &Q)
{
Q.front = Q.rear = 0;
}
bool IsEmptyQueue(const Queue &Q)
{
return Q.front == Q.rear;
}
void EnQueue(Queue &Q, QElemType &v)
{
Q.elem[Q.rear] = v;
++Q.rear;
}
QElemType DeQueue(Queue &Q)
{
QElemType e;
e = Q.elem[Q.front];
++Q.front;
return e;
}
10-02
3万+
03-21
9223