图的广度遍历

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的第一个邻接结点ww = 顶点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;	
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值