图的广度优先遍历BFS(分别以邻接矩阵和邻接链表实现)
来源:互联网 发布:撕衣服软件 编辑:程序博客网 时间:2024/06/16 21:02
算法描述:
设图G的初始状态是所有顶点均未被访问过,在G中的任选一顶点vi为初始出发点,则广度优先遍历 可定义如下:首先,访问初始出发点vi,接着依次访问vi的所有邻接点w1,w2,...,wk;然后,依次访问w1,w2,...,wk 的邻接的所有未被访问过的顶点,依次类推,直到图中所有的和初始点vi有路径相通的顶点都被访问过为止。
算法实现:
(1) 访问初始顶点vi
(2) 置顶点v已访问标记
(3) 顶点v入队
(4) while(队不空){
取出队首顶点i;
依次搜索顶点i的所有的邻接点;
如果未被访问,则访问该邻接点,并将其入队。
}
用邻接矩阵实现图的广度优先遍历的源代码如下:
- /**
- * 广度遍历图
- **/
- void BFS_MG(MGraph MG,int s){
- //清空访问标志
- init_Visit();
- //定义队列,用于保存当前节点的邻接顶点
- int Q[MAX_VEX_NUM];
- int front = 0;
- int rear = 0;
- int i,j,k;
- printf("%c\t",MG.vexs[s]);
- visit[s] = 1;
- Q[rear++] = s;
- //遍历队列
- while(front < rear){
- i = Q[front++];
- for (j = 1; j <= MG.vexnum;j++){
- if(visit[j] == 0 && MG.arcs[i][j] == 1){
- printf("%c\t",MG.vexs[j]);
- visit[j] = 1;
- Q[rear++] = j;
- }
- }
- }
- }
用邻接表实现图的广度优先遍历的源代码如下:
- /**
- * 广度遍历图
- **/
- void BFS_AG(ALGraph AG,int s){
- ArcPtr p;
- //清空访问标志
- init_Visit();
- //定义队列,用于保存当前节点的邻接顶点
- int Q[MAX_VERTEX_NUM];
- int front = 0;
- int rear = 0;
- int i,j,k;
- printf("%c\t",AG.vertices[s]);
- visit[s] = 1;
- Q[rear++] = s;
- //遍历队列
- while(front < rear){
- i = Q[front++];
- for(p = AG.vertices[i].firstarc;p;p=p->nextarc){
- j = p->adjvex;
- if(visit[j] == 0){
- printf("%c\t",AG.vertices[j].vexdata);
- visit[j] = 1;
- Q[rear++] = j;
- }
- }
- }
- }
算法说明:
对有具有n个顶点和e条边的连通图,因为每个基点均需要入队一次,所以while语句需要执行n次,对于邻接矩阵而言,内循环搜索邻接点时同样需要执行n次,故BFS_MG的时间复杂度为O(n^2);对于邻接表而言,内循环的次数取决于各顶点的边表结点的总个数,所以BFS_AG的时间复杂度为O(n+e)。
可以看出,广度优先遍历需要一个辅助队列,和标志数组,故空间复杂度为O(n)。
完整代码:
用邻接矩阵实现广度优先遍历的完整代码:
- /*
- ============================================================================
- Name : Graph.c
- Author : jesson20121020
- Version : 1.0
- Description : create Graph using Adjacency Matrix, Ansi-style
- ============================================================================
- */
- #include <stdio.h>
- #include <stdlib.h>
- #define MAX_VEX_NUM 50
- typedef char VertexType;
- typedef enum {
- DG, UDG
- } GraphType;
- typedef struct {
- VertexType vexs[MAX_VEX_NUM];
- int arcs[MAX_VEX_NUM][MAX_VEX_NUM];
- int vexnum, arcnum;
- GraphType type;
- } MGraph;
- //设置图中顶点访问标志
- int visit[MAX_VEX_NUM];
- /**
- * 根据名称得到指定顶点在顶点集合中的下标
- * vex 顶点
- * return 如果找到,则返回下标,否则,返回0
- */
- int getIndexOfVexs(char vex, MGraph *MG) {
- int i;
- for (i = 1; i <= MG->vexnum; i++) {
- if (MG->vexs[i] == vex) {
- return i;
- }
- }
- return 0;
- }
- /**
- * 创建邻接矩阵
- */
- void create_MG(MGraph *MG) {
- int i, j, k;
- int v1, v2, type;
- char c1, c2;
- printf("Please input graph type DG(0) or UDG(1) :");
- scanf("%d", &type);
- if (type == 0)
- MG->type = DG;
- else if (type == 1)
- MG->type = UDG;
- else {
- printf("Please input correct graph type DG(0) or UDG(1)!");
- return;
- }
- printf("Please input vexmun : ");
- scanf("%d", &MG->vexnum);
- printf("Please input arcnum : ");
- scanf("%d", &MG->arcnum);
- getchar();
- for (i = 1; i <= MG->vexnum; i++) {
- printf("Please input %dth vex(char):", i);
- scanf("%c", &MG->vexs[i]);
- getchar();
- }
- //初始化邻接矩阵
- for (i = 1; i <= MG->vexnum; i++) {
- for (j = 1; j <= MG->vexnum; j++) {
- MG->arcs[i][j] = 0;
- }
- }
- //输入边的信息,建立邻接矩阵
- for (k = 1; k <= MG->arcnum; k++) {
- printf("Please input %dth arc v1(char) v2(char) : ", k);
- scanf("%c %c", &c1, &c2);
- v1 = getIndexOfVexs(c1, MG);
- v2 = getIndexOfVexs(c2, MG);
- if (MG->type == 1)
- MG->arcs[v1][v2] = MG->arcs[v2][v1] = 1;
- else
- MG->arcs[v1][v2] = 1;
- getchar();
- }
- }
- /**
- * 打印邻接矩阵和顶点信息
- */
- void print_MG(MGraph MG) {
- int i, j;
- if(MG.type == DG){
- printf("Graph type: Direct graph\n");
- }
- else{
- printf("Graph type: Undirect graph\n");
- }
- printf("Graph vertex number: %d\n",MG.vexnum);
- printf("Graph arc number: %d\n",MG.arcnum);
- printf("Vertex set:\n ");
- for (i = 1; i <= MG.vexnum; i++)
- printf("%c\t", MG.vexs[i]);
- printf("\nAdjacency Matrix:\n");
- for (i = 1; i <= MG.vexnum; i++) {
- j = 1;
- for (; j < MG.vexnum; j++) {
- printf("%d\t", MG.arcs[i][j]);
- }
- printf("%d\n", MG.arcs[i][j]);
- }
- }
- /**
- * 初始化顶点访问标志
- **/
- void init_Visit(){
- int i;
- for(i = 0;i < MAX_VEX_NUM;i++)
- visit[i] = 0;
- }
- /**
- * 广度遍历图
- **/
- void BFS_MG(MGraph MG,int s){
- //清空访问标志
- init_Visit();
- //定义队列,用于保存当前节点的邻接顶点
- int Q[MAX_VEX_NUM];
- int front = 0;
- int rear = 0;
- int i,j,k;
- printf("%c\t",MG.vexs[s]);
- visit[s] = 1;
- Q[rear++] = s;
- //遍历队列
- while(front < rear){
- i = Q[front++];
- for (j = 1; j <= MG.vexnum;j++){
- if(visit[j] == 0 && MG.arcs[i][j] == 1){
- printf("%c\t",MG.vexs[j]);
- visit[j] = 1;
- Q[rear++] = j;
- }
- }
- }
- }
- /**
- * 主函数
- */
- int main(void) {
- MGraph MG;
- create_MG(&MG);
- print_MG(MG);
- printf("\nThe result of BFS:\n");
- BFS_MG(MG,1);
- return EXIT_SUCCESS;
- }
用邻接表实现广度优先遍历的完整代码:
- /*
- ============================================================================
- Name : ALGraph.c
- Author : jesson20121020
- Version :
- Copyright : Your copyright notice
- Description : Graph using linkList, Ansi-style
- ============================================================================
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdio.h>
- #define MAX_VERTEX_NUM 50
- typedef enum {
- DG, UDG
- } GraphType;
- typedef char VertexType;
- //表节点
- typedef struct ArcNode {
- int adjvex; //邻接节点
- int weight; //边权重
- struct ArcNode *nextarc; //下一个节点指针
- } ArcNode, *ArcPtr;
- //头节点
- typedef struct {
- VertexType vexdata;
- int id;
- ArcPtr firstarc;
- } VNode;
- //头节点数组
- typedef struct {
- VNode vertices[MAX_VERTEX_NUM];
- int vexnum, arcnum;
- GraphType type;
- } ALGraph;
- int visit[MAX_VERTEX_NUM];
- /**
- * 根据顶点字符得到在顶点数组中的下标
- */
- int getIndexOfVexs(char vex, ALGraph *AG) {
- int i;
- for (i = 1; i <= AG->vexnum; i++) {
- if (AG->vertices[i].vexdata == vex) {
- return i;
- }
- }
- return 0;
- }
- /**
- * 创建邻接表
- */
- void create_AG(ALGraph *AG) {
- ArcPtr p,q;
- int i, j, k, type;
- VertexType v1, v2;
- printf("Please input graph type UG(0) or UDG(1) :");
- scanf("%d", &type);
- if (type == 0)
- AG->type = DG;
- else if (type == 1)
- AG->type = UDG;
- else {
- printf("Please input correct graph type UG(0) or UDG(1)!");
- return;
- }
- printf("please input vexnum:");
- scanf("%d", &AG->vexnum);
- printf("please input arcnum:");
- scanf("%d", &AG->arcnum);
- getchar();
- for (i = 1; i <= AG->vexnum; i++) {
- printf("please input the %dth vex(char) : ", i);
- scanf("%c", &AG->vertices[i].vexdata);
- getchar();
- AG->vertices[i].firstarc = NULL;
- }
- for (k = 1; k <= AG->arcnum; k++) {
- printf("please input the %dth arc v1(char) v2(char) :", k);
- scanf("%c %c", &v1, &v2);
- i = getIndexOfVexs(v1, AG);
- j = getIndexOfVexs(v2, AG);
- //根据图的类型创建邻接表
- //方法1,插入到链表头
- /*
- if (AG->type == DG) { //有向图
- p = (ArcPtr) malloc(sizeof(ArcNode));
- p->adjvex = j;
- p->nextarc = AG->vertices[i].firstarc;
- AG->vertices[i].firstarc = p;
- } else { //无向图
- p = (ArcPtr) malloc(sizeof(ArcNode));
- p->adjvex = j;
- p->nextarc = AG->vertices[i].firstarc;
- AG->vertices[i].firstarc = p;
- p = (ArcPtr) malloc(sizeof(ArcNode));
- p->adjvex = i;
- p->nextarc = AG->vertices[j].firstarc;
- AG->vertices[j].firstarc = p;
- }
- */
- //方法2,插入到链表尾
- if (AG->type == DG) { //有向图
- p = (ArcPtr) malloc(sizeof(ArcNode));
- p->adjvex = j;
- //表为空
- if(AG->vertices[i].firstarc == NULL){
- AG->vertices[i].firstarc = p;
- }
- else{
- //找最后一个表节点
- q = AG->vertices[i].firstarc;
- while(q->nextarc != NULL){
- q = q->nextarc;
- }
- q->nextarc = p;
- }
- p->nextarc = NULL;
- } else { //无向图
- p = (ArcPtr) malloc(sizeof(ArcNode));
- p->adjvex = j;
- //表为空
- if(AG->vertices[i].firstarc == NULL){
- AG->vertices[i].firstarc = p;
- }
- else{
- //找最后一个表节点
- q = AG->vertices[i].firstarc;
- while(q->nextarc != NULL){
- q = q->nextarc;
- }
- q->nextarc = p;
- }
- p->nextarc = NULL;
- p = (ArcPtr) malloc(sizeof(ArcNode));
- p->adjvex = i;
- //表为空
- if(AG->vertices[j].firstarc == NULL){
- AG->vertices[j].firstarc = p;
- }
- else{
- //找最后一个表节点
- q = AG->vertices[j].firstarc;
- while(q->nextarc != NULL){
- q = q->nextarc;
- }
- q->nextarc = p;
- }
- p->nextarc = NULL;
- }
- getchar();
- }
- }
- /**
- * 输出图的相关信息
- */
- void print_AG(ALGraph AG) {
- ArcPtr p;
- int i;
- if (AG.type == DG) {
- printf("Graph type: Direct graph\n");
- } else {
- printf("Graph type: Undirect graph\n");
- }
- printf("Graph vertex number: %d\n", AG.vexnum);
- printf("Graph arc number: %d\n", AG.arcnum);
- printf("Vertex set :\n");
- for (i = 1; i <= AG.vexnum; i++)
- printf("%c\t", AG.vertices[i].vexdata);
- printf("\nAdjacency List:\n");
- for (i = 1; i <= AG.vexnum; i++) {
- printf("%d", i);
- p = AG.vertices[i].firstarc;
- while (p != NULL) {
- printf("-->%d", p->adjvex);
- p = p->nextarc;
- }
- printf("\n");
- }
- }
- /**
- * 初始化顶点访问标志
- **/
- void init_Visit(){
- int i;
- for(i = 0;i < MAX_VERTEX_NUM;i++)
- visit[i] = 0;
- }
- /**
- * 广度遍历图
- **/
- void BFS_AG(ALGraph AG,int s){
- ArcPtr p;
- //清空访问标志
- init_Visit();
- //定义队列,用于保存当前节点的邻接顶点
- int Q[MAX_VERTEX_NUM];
- int front = 0;
- int rear = 0;
- int i,j,k;
- printf("%c\t",AG.vertices[s]);
- visit[s] = 1;
- Q[rear++] = s;
- //遍历队列
- while(front < rear){
- i = Q[front++];
- for(p = AG.vertices[i].firstarc;p;p=p->nextarc){
- j = p->adjvex;
- if(visit[j] == 0){
- printf("%c\t",AG.vertices[j].vexdata);
- visit[j] = 1;
- Q[rear++] = j;
- }
- }
- }
- }
- int main(void) {
- ALGraph AG;
- create_AG(&AG);
- print_AG(AG);
- printf("\nThe result of BFS:\n");
- BFS_AG(AG,1);
- return EXIT_SUCCESS;
- }
- 图的广度优先遍历BFS(分别以邻接矩阵和邻接链表实现)
- 图的深度优先遍历DFS(分别以邻接矩阵和邻接表实现)
- 邻接表实现--图的深度优先遍历DFS和广度优先遍历BFS
- 数据结构实验图论:基于邻接矩阵/邻接表的广度优先搜索遍历(BFS)
- 图的广度优先搜索(BFS)、深度优先搜索(DFS)(邻接矩阵法和邻接表法java实现)
- 邻接矩阵实现--图的深度优先遍历DFS和广度优先遍历BFS
- 图的广度优先搜索遍历(邻接表&邻接矩阵)(C++)
- 图的广度优先遍历,基于邻接链表实现
- 广度优先算法 分别基于邻接链表和邻接矩阵方式
- 邻接表-图的遍历-广度和深度优先遍历
- c语言编程 输出一个无向图的邻接表,邻接矩阵,进行深度和广度优先遍历
- 图的广度优先遍历BFS(邻接矩阵表示法)
- 图的广度优先遍历BFS(邻接矩阵表示法)
- 无向图的深度优先遍历和广度优先遍历(邻接链表)
- 建立图的邻接表储存并实现深度优先和广度优先遍历
- 数据结构实验图论:基于邻接矩阵/邻接表的广度优先搜索遍历
- 邻接图的广度优先遍历和深度优先遍历
- C++实现图的邻接矩阵的创建以及其深度优先遍历和广度优先遍历
- (3)风色从零单排《C++ Primer》 重要的基本类型
- C语言经典算法100例1-5
- nginx配置文件解析
- Python学习(一)----输入和输出
- Maven 学习资料汇总
- 图的广度优先遍历BFS(分别以邻接矩阵和邻接链表实现)
- 假如有人欺骗了你•••
- JVM 基础知识(GC)
- HTML总结
- ios8.0下CLLocationManager定位服务需要授权了
- iOS开发之字体的替换
- magento修改货币符号和货币符号的位置
- 数据标准化
- LeetCode 之 Remove Duplicates from Sorted List I II — C++ 实现