广度优先搜索遍历
广度优先搜索遍历类似与树的层次遍历,过程如下:
(1) 从图中的某个顶点v出发,访问v
(2) 依次访问v的各个未曾访问的邻接点
(3) 分别从这些邻接点出发依次访问他们的邻接点,并使"先被访问的顶点的邻接点" 先于" 后被访问 的顶点的邻接点"被访问。重复步骤(3),直至图中所有已被访问的顶点的邻接点都被访问到。
图例演示:
(图片来源于网络)
附上代码:
/*
广度优先搜索遍历类似与树的层次遍历,过程如下:
(1) 从图中的某个顶点v出发,访问v
(2) 依次访问v的各个未曾访问的邻接点
(3) 分别从这些邻接点出发依次访问他们的邻接点,并使"先被访问的顶点的邻接点" 先于" 后被访问的顶点的邻接点"被访问。
重复步骤(3),直至图中所有已被访问的顶点的邻接点都被访问到。
*/
//1 2 1 2 4 2 4 8 3 2 5 4 5 8 5 1 3 6 3 6 7 3 7 8 6 7 9
#include<iostream>
#include<string>
#include<queue>
using namespace std;
#define OK 1
#define ERROR 0
#define MAXint 32767 //表示无穷大
#define MVNum 100 //最大顶点数
bool visited[MVNum] = { false };//标识数组,初始值为false
//邻接矩阵的结构
typedef struct
{
string vexs[MVNum];//顶点表
int arcs[MVNum][MVNum];//邻接矩阵,也就是表示边的权值
int vexnum, arcnum;//图的顶点数和边的个数
}AMGraph;
//邻接矩阵的结构
//邻接表的结构
typedef struct ArcNode {//边结点
int adjvex;//该边所指向的顶点的位置
struct ArcNode* nextarc;//指向下一条边的指针
int info;//和边相关的信息
}ArcNode;
typedef struct {//顶点信息
string data;
ArcNode* firstarc;//指向第一条依附该顶点的边的指针
}VNode, AdjList[MVNum];
typedef struct//邻接表
{
AdjList vertices;//顶点信息
int vexnum, arcnum;//图的当前顶点数和边数
}ALGraph;
//邻接表的结构
//查询结点位置
int Locate(AMGraph G, string v)
{
for (int i = 0; i < G.vexnum; i++)
{
if (G.vexs[i] == v)
{
return i;
}
}
return -1;
}
//查询结点位置
int Locate(ALGraph G, string v)//Locate重载
{
for (int i = 0; i < G.vexnum; i++)
{
if (G.vertices[i].data == v)
{
return i;
}
}
return -1;
}
//创建邻接矩阵
int CreateUDN(AMGraph& G)//无向图的构造
{
cout << "请输入图的顶点数和边数:";
cin >> G.vexnum >> G.arcnum;
cout << "各节点的信息:";
for (int i = 0; i < G.vexnum; i++)
{
cin >> G.vexs[i];
}
cout << "各边的顶点和权值:";
for (int i = 0; i < G.vexnum; i++)//初始化边的权值为MAXINT
{
for (int j = 0; j < G.vexnum; j++)
{
G.arcs[i][j] = MAXint;
}
}
for (int k = 0; k < G.arcnum; k++)//构造邻接矩阵
{
string v1, v2;
int w;//边的两个顶点以及权值
cin >> v1 >> v2 >> w;
int i = Locate(G, v1);//找到点的位置
int j = Locate(G, v2);
G.arcs[i][j] = w;//赋予权值
G.arcs[j][i] = G.arcs[i][j];
}
return OK;
}
//创建邻接矩阵
//创建邻接表
int CreateUDG(ALGraph& G)
{
cout << "请输入图的顶点数和边数:";
cin >> G.vexnum >> G.arcnum;//输入顶点数和边数
cout << "输入各节点的信息:";
for (int i = 0; i < G.vexnum; i++)//初始化顶点信息
{
cin >> G.vertices[i].data;//输入顶点的信息
G.vertices[i].firstarc = NULL;//firstarc置空
}
cout << "输入各边的顶点和权值:";
for (int k = 0; k < G.arcnum; k++)
{
string v1, v2;
int weight;//权值
cin >> v1 >> v2 >> weight;//输入一条边依附的两个顶点
int i = Locate(G, v1);
int j = Locate(G, v2);
ArcNode* p1 = new ArcNode;
p1->info = weight;
p1->adjvex = j;
p1->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p1;
ArcNode* p2 = new ArcNode;
p2->info = weight;
p2->adjvex = i;
p2->nextarc = G.vertices[j].firstarc;
G.vertices[j].firstarc = p2;
}
return OK;
}
//创建邻接表
//广度优先搜索遍历邻接矩阵
void BFS_AM(AMGraph G, int v)
{
cout << G.vexs[v];//输出节点信息
visited[v] = true;//标志置为true
queue <int> q;//初始化队列
q.push(v);//v入队
while (!q.empty())//队非空
{
int t = q.front();//队头元素
q.pop();//元素出队
for (int i = 0; i < G.vexnum; i++)//找到v的邻接点
{
if (G.arcs[t][i] != MAXint && !visited[i])
{
cout << G.vexs[i];
visited[i] = true;
q.push(i);//邻接点入队
}
}
}
}
//广度优先搜索遍历邻接矩阵
//广度优先搜索遍历邻接表
void BFS_AL(ALGraph G, int v)
{
cout << G.vertices[v].data;//输出结点值
visited[v] = true;//标志置为true
queue < int> q;//队列初始化
q.push(v);
while (!q.empty())//队非空
{
int t = q.front();//取队头元素
q.pop();//队头元素出栈
ArcNode* p = G.vertices[t].firstarc;//p是v的邻接点
while (p)//输出邻接点信息
{
int w = p->adjvex;//邻接点的序号
if (!visited[w])
{
cout << G.vertices[w].data;
visited[w] = true;
q.push(w);//邻接点入栈
}
p = p->nextarc;//下一个邻接点
}
}
}
//广度优先搜索遍历邻接表
int main()
{
ALGraph G;
CreateUDG(G);
int v;
cout << "您要遍历的位置:";
cin >> v;
BFS_AL(G, v);
return 0;
}