【自己动手写数据结构】 -- 图的广度优先搜索算法

/*
 * 基于邻接矩阵存储的图的广度优先搜索算法(BFS)
 */

#include<stdio.h>
#include<stdlib.h>

typedef int Bool;
#define FALSE 0
#define TRUE 1

//定义顶点类型
typedef char VertexType;
//定义边上权值类型
typedef int EdgeType;

//定义图中顶点数目的最大值
#define MAXVEX 30
typedef struct Graph {
	//存储顶点的一维数组
	VertexType vertex[MAXVEX];
	//存储边信息的二维数组
	EdgeType edge[MAXVEX][MAXVEX];
	//图中当前的顶点数和边数
	int verNum;
	int edgeNum;
}Graph;

//顶点访问标志的数组
Bool visited[MAXVEX];

#define MAXSIZE 30
typedef struct {
	int data[MAXSIZE];
	int front;
	//尾指针,若队列不为空,指向对为元素的下一个位置
	int rear;
}Queue;

//初始化一个空队列
void initQueue(Queue *Q) {
	Q->front = 0;
	Q->rear = 0;
}

//判断队列是否为空
Bool isEmpty(Queue Q) {
	return Q.front == Q.rear;
}

//往队列中插入元素elem
Bool enQueue(Queue *Q, int elem) {
	if((Q->rear+1)%MAXSIZE == Q->front) {
		return FALSE;
	}
	Q->data[Q->rear] = elem;
	Q->rear = (Q->rear+1)%MAXSIZE;
	return TRUE;
}

//删除队列中的队头元素
Bool deQueue(Queue *Q, int *elem) {
	if(Q->front == Q->rear) {
		return FALSE;
	}
	*elem = Q->data[Q->front];
	Q->front = (Q->front+1) % MAXSIZE;
	return TRUE;
}

//创建图
void createGraph(Graph *G) {
	G->verNum = 6;
	G->edgeNum = 8;

	//建立顶点表
	G->vertex[0] = 'A';
	G->vertex[1] = 'B';
	G->vertex[2] = 'C';
	G->vertex[3] = 'D';
	G->vertex[4] = 'E';
	G->vertex[5] = 'F';

	//初始化图
	for(int i = 0; i < G->verNum; i++) {
		for(int j = 0; j < G->verNum; j++) {
			G->edge[i][j] = 0;
		}
	}

	//初始化边信息
	G->edge[0][2] = 1;
	G->edge[0][4] = 1;

	G->edge[1][2] = 1;
	G->edge[1][5] = 1;

	G->edge[2][0] = 1;
	G->edge[2][1] = 1;
	G->edge[2][3] = 1;
	G->edge[2][5] = 1;

	G->edge[3][2] = 1;
	G->edge[3][5] = 1;

	G->edge[4][0] = 1;
	G->edge[4][5] = 1;

	G->edge[5][1] = 1;
	G->edge[5][2] = 1;
	G->edge[5][3] = 1;
	G->edge[5][3] = 1;

	printf("该图的邻接矩阵为:\n");
	for(int i = 0; i < G->verNum; i++) {
		for(int j = 0; j < G->verNum; j++) {
			printf("%d\t", G->edge[i][j]);
		}
		printf("\n");
	}
}

//i为指定的开始顶点 下标
void BFSTraverse(Graph G, int i) {
	//声明并初始化一个遍历顶点用的辅助队列
	Queue Q;
	initQueue(&Q);
	//设访问标志为FALSE
	for(int k = 0; k < G.verNum; k++) {
		visited[k] = FALSE;
	}

	//如果该结点未被访问过就进行相应处理
	if(!visited[i]) {
		//设置当前结点访问标志
		visited[i] = TRUE;
		printf("%c ", G.vertex[i]);
		enQueue(&Q, i);
		while(!isEmpty(Q)) {
			deQueue(&Q, &i);
			//依次访问与该顶点有边相连的邻接顶点
			for(int j = 0; j < G.verNum; j++) {
				if(G.edge[i][j] == 1 && !visited[j]) {
					visited[j] = TRUE;
					printf("%c ", G.vertex[j]);
					enQueue(&Q, j);
				}
			}
		}
	}

}


int main(void) {
	Graph G;
	createGraph(&G);
	printf("\n广度遍历:");
	BFSTraverse(G, 0);
}












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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值