1.图的广度遍历-----BFS
1.1基本思想
分层搜索的过程,和树的层次遍历算法相似,需要队列保存已经遍历过的顶点顺序,按照出队列的顺序访问这些顶点的邻接结点。
1.2算法描述
伪代码描述 | 细化描述 |
(1)初始化 | (1)设立访问标志数组visited[N] = 0,某顶点被访问后,则相应的下标元素置1 (2)初始化队列Q,输入要访问的节点 |
(2)顶点v入队列 | 访问顶点v;visit[v] = 1;顶点v出队列 |
(3)当队列非空时则继续执行,否则算法结束 | while(队列Q非空) |
(4)出队列取得对头顶点v;访问节点v的=并标记顶点v被访问 | v = 队列Q的对头元素出队 |
(5)查找节点v的第一个邻接结点w | w = 顶点v的第一个临界点 |
(6)若w未被访问过,则w入队列 | while(w存在) 如果w没有被访问 visited[w] = 1; 顶点w入队列 |
(7)继续查找v的新的邻接节点w,转到(6),如果v没有新的邻接结点则转到(3)执行 | w = 顶点v的下一个邻接点 |
1.3BFS程序实现
1.3.1基于邻接矩阵的BFS的实现
(1)头结点,全局变量,数据类型的引入
#include <stdio.h>
#define TURE 1 //定义True为1
#define FALSE 0 //FALSE为0
#define N 9 //顶点数为9
int visited[N]; //定义标志数组(看是否访问过该节点)
int AdjMatrix[N][N] = //定义邻接矩阵
{{0,1,0,0,0,0,0,0,0},
{1,0,0,0,1,1,0,1,1},
{0,0,0,0,0,1,1,0,0},
{0,0,0,0,1,0,0,0,1},
{0,1,0,1,0,1,1,0,1},
{0,1,1,0,1,0,1,0,0},
{0,0,1,0,1,1,0,0,0},
{0,1,0,0,0,0,0,0,0},
{0,1,0,1,1,0,0,0,0}};
(2)找顶点v相邻点i的后一个相邻点
int FindVex(int v,int i){
while(AdjMatrix[v][i] == 0){ //如果邻接矩阵中的数值为0,即两点之间没有边,那么i++,继续找,返回与v顶点有边的相邻点i之后的第一个节点
i++;
}
if(i < N){ //该点的索引在最大点数之内
return i; //如果有相邻点,那么返回相邻点之后的内个点索引
}
else{ //如果没有那么返回-1,该点的点数在最大点数之外
return -1;
}
}
(3)输出广度优先的遍历序列
void GraphBFS(int v){
int flag; //定义旗帜 用来记录把节点插入队列
SeqQueue struc; //定义序列
SeqQueue *sq; //定义指向序列的指针
sq = &struc; //把指针指向struc队列所在的区域
int w,k; //w,k用来记录存入队列和从队列中删除的节点
int count = 0; //count用来计数,计算遍历的总数为节点总数
initialize_SqQueue(sq); //首先初始化队列
printf("BFS序列"); //输出广度遍历序列
printf("%d",v); //访问第一个顶点
visit[v]= 1; //设置访问标记数组,把该点标记为访问过
count++; //计数器加一
flag = Insert_SqQueue(sq,v); //把v节点插入队列
while(!Empty_sqQueue(sq)){ //如果队列不为空
if(count == N){ //如果遍历次数完成,那么退出遍历
break;
}
k = Delete_sqQueue(sq); //获得队列的第一个元素索引
v = sq->data[k]; //获取队列的第一个元素值
w = FindVex(v,0); //找到该节点的临界点
while(w != -1){ //如果有临界点
if(visited[w] != 1){ //如果临界点没有访问过
Visited[w] = 1; //那么访问临界点,并设置访问标记为1 ,访问计数器++,并把该点压入队列
printf("%d",w);
count++;
flag = Insert_SqQueue(sq,w);
}
w = FindVex(v,w + 1); //继续寻找w节点后的下一个与v关联的节点
}
}
printf("\n"); //输出空格
}
(4)主函数
int main(){
GraphBFS(0); //从顶点1开始遍历,对应下标为0
return 0;
}