深度优先搜索(Breadth  First Search),类似于树的层序遍历,搜索模型是队列,还是以下面的无向图为例:

实验环境是Ubuntu 14.04 x86

伪代码实现如下:

其中u 为 v 的先辈或父母。

BFS(G, s)

for each vertex u ∈ V [G] - {s}
do color[u] ← WHITE
d[u] ← ∞
π[u] ← NIL //除了源顶点s之外,第1-4行置每个顶点为白色,置每个顶点u的d[u]为无穷大,置每个顶点的父母为NIL。
color[s] ← GRAY // 将源顶点s置为灰色,这是因为在过程开始时,源顶点已被发现。
d[s] ← 0
π[s] ← NIL //将源顶点的父顶点置为NIL。
Q ← Ø
ENQUEUE(Q, s) //第8、9行,初始化队列Q,使其仅含源顶点s。
while Q ≠ Ø
do u ← DEQUEUE(Q) //确定队列头部Q头部的灰色顶点u,并将其从Q中去掉。
for each v ∈ Adj[u] //for循环考察u的邻接表中的每个顶点v
do if color[v] = WHITE
then color[v] ← GRAY
d[v] ← d[u] + 1
π[v] ← u //u记为该顶点的父母
ENQUEUE(Q, v) //插入队列中
color[u] ← BLACK

队列推荐使用链式队列。

邻接表实现:

#include <stdio.h>
#include <malloc.h> #define MAX_VERTEX_NUM 50 typedef char vertexType;
typedef int edgeType;
typedef int QueueElemType; /* 边表 */
typedef struct ArcNode
{
int adjIndex;
struct ArcNode *nextArc;
edgeType weight;
}ArcNode; /* 顶点表 */
typedef struct VNode
{
vertexType data;
ArcNode *firstArc;
}VNode, AdjList[MAX_VERTEX_NUM]; /* 图结构 */
typedef struct
{
AdjList adjList;
int vexNum;
int edgeNum;
}ALGraph; typedef struct QueueNode
{
QueueElemType data;
struct QueueNode *next;
}QueueNode; typedef struct
{
QueueNode *front;
QueueNode *rear;
}LinkQueue; int visit[MAX_VERTEX_NUM] = {0}; void initLinkQueue(LinkQueue *queue)
{
QueueNode *head = (QueueNode*)malloc(sizeof(QueueNode));
if(head == NULL)
{
printf("malloc failed\n");
return;
} head->next = NULL;
queue->front = queue->rear = head; return;
} void insertLinkQueue(LinkQueue *queue, QueueElemType data)
{
QueueNode *newNode = (QueueNode *)malloc(sizeof(QueueNode));
if(NULL == newNode)
{
printf("malloc failed\n");
return;
} newNode->data = data;
newNode->next = NULL; queue->rear->next = newNode;
queue->rear = newNode; return;
} int deleteLinkQueue(LinkQueue *queue, QueueElemType *data)
{
QueueNode *p; if (queue->front == queue->rear)
{
printf("no element!\n");
return 0;
} p = queue->front->next;
*data = p->data; queue->front->next = p->next;
if (p == queue->rear)
{
queue->rear = queue->front;
} free(p);
return 1;
} void BFSTraverse(ALGraph G)
{
QueueElemType q;
LinkQueue queue;
ArcNode *adjEdge;
int index = 0; initLinkQueue(&queue); for (int i = 0; i < G.vexNum; i++)
{
if (!visit[i])
{
visit[i] = 1;
printf("%c ", G.adjList[i].data);
insertLinkQueue(&queue, i); while (deleteLinkQueue(&queue, &q))
{
adjEdge = G.adjList[q].firstArc;
while (adjEdge)
{
index = adjEdge->adjIndex; if (!visit[index])
{
visit[index] = 1;
printf("%c ", G.adjList[index].data); insertLinkQueue(&queue, index);
}
adjEdge = adjEdge->nextArc;
}
}
} } } void CreateALGraph(ALGraph *G)
{
int i, j, k;
ArcNode *e;
int c; printf("输入顶点数和边数:\n");
scanf("%d %d", &G->vexNum, &G->edgeNum);
setbuf(stdin, NULL); for (i = 0; i < G->vexNum; i++)
{
printf("输入顶点信息:\n");
scanf("%c", &G->adjList[i].data);
G->adjList[i].firstArc = NULL; while((c = getchar()) != '\n' && c != EOF);
} for (k = 0; k < G->edgeNum; k++)
{
printf("输入边(vi,vj)的顶点序号i,j:\n");
scanf("%d %d", &i, &j); while((c = getchar()) != '\n' && c != EOF); e = (ArcNode*)malloc(sizeof(ArcNode));
if (NULL == e)
{
return;
} e->adjIndex = j;
e->nextArc = G->adjList[i].firstArc;
G->adjList[i].firstArc = e; // double direction copy
e = (ArcNode *)malloc(sizeof(ArcNode));
if (NULL == e)
{
return;
}
e->adjIndex = i;
e->nextArc = G->adjList[j].firstArc;
G->adjList[j].firstArc = e;
}
} int main(int argc, char const *argv[])
{
ALGraph G;
CreateALGraph(&G); BFSTraverse(G);
return 0;
}

运行结果: A F B G E I C H D

邻接矩阵实现:

#include <stdio.h>
#include <malloc.h> #define MAX_VERTEX_NUM 50 typedef char vertexType;
typedef int edgeType;
typedef int QueueElemType; typedef struct
{
vertexType vexs[MAX_VERTEX_NUM];
edgeType arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int vexNum;
int edgeNum;
}Graph; typedef struct QueueNode
{
QueueElemType data;
struct QueueNode *next;
}QueueNode; typedef struct
{
QueueNode *front;
QueueNode *rear;
}LinkQueue; int visit[MAX_VERTEX_NUM] = {0}; void initLinkQueue(LinkQueue *queue)
{
QueueNode *head = (QueueNode*)malloc(sizeof(QueueNode));
if(head == NULL)
{
printf("malloc failed\n");
return;
} head->next = NULL;
queue->front = queue->rear = head; return;
} void insertLinkQueue(LinkQueue *queue, QueueElemType data)
{
QueueNode *newNode = (QueueNode *)malloc(sizeof(QueueNode));
if(NULL == newNode)
{
printf("malloc failed\n");
return;
} newNode->data = data;
newNode->next = NULL; queue->rear->next = newNode;
queue->rear = newNode; return;
} int deleteLinkQueue(LinkQueue *queue, QueueElemType *data)
{
QueueNode *p; if (queue->front == queue->rear)
{
printf("no element!\n");
return 0;
} p = queue->front->next;
*data = p->data; queue->front->next = p->next;
if (p == queue->rear)
{
queue->rear = queue->front;
} free(p);
return 1;
}
void CreateALGraph(Graph *G)
{
int i, j, k;
int c; printf("输入顶点数和边数:\n");
scanf("%d %d", &G->vexNum, &G->edgeNum);
setbuf(stdin, NULL); for (i = 0; i < G->vexNum; i++)
{
printf("输入第%d个顶点信息:\n", i + 1);
scanf("%c", &G->vexs[i]); while((c = getchar()) != '\n' && c != EOF);
} for (i = 0; i < G->vexNum; i++)
{
for (j = 0; j < G->vexNum; j++)
{
G->arc[i][j] = 0;
}
} for (k = 0; k < G->edgeNum; k++)
{
printf("输入边(vi,vj)的下标i,j:\n");
scanf("%d %d", &i, &j); while((c = getchar()) != '\n' && c != EOF); // set a default weight
G->arc[i][j] = G->arc[j][i] = 1;
}
} void BFSTraverse(Graph G)
{
LinkQueue queue;
QueueElemType q; initLinkQueue(&queue); for(int i = 0; i < G.vexNum; i++)
{
if (!visit[i])
{
visit[i] = 1;
printf("%c ", G.vexs[i]); insertLinkQueue(&queue, i);
while (deleteLinkQueue(&queue, &q))
{
for (int j = 0; j < G.vexNum; j++)
{
if (G.arc[q][j] == 1 && !visit[j])
{
visit[j] = 1;
printf("%c ", G.vexs[j]);
insertLinkQueue(&queue, j);
}
}
}
}
}
} int main(int argc, char const *argv[])
{
Graph G;
CreateALGraph(&G); BFSTraverse(G);
return 0;
}

运行结果:A B F C G I E D H

图算法之BFS的更多相关文章

  1. 图算法(一)——基本图算法(BFS,DFS及其应用)(1)

    1)BFS 广度优先搜索:给定源节点s,生成广度优先搜索树广度优先搜索树中从节点s到节点v的简单路径对应的就是s到v的最短路径(边数最少的路径)广度优先:将已发现节点与未发现节点之间的边界(灰色节点) ...

  2. 经典图算法Java代码实践:BFS,DFS以及几种最短路径算法

    public class City { String name; int id; static int idCounter = 0; public City(String name) { this.n ...

  3. 程序员的算法课(18)-常用的图算法:广度优先(BFS)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  4. 图算法(一)——基本图算法(BFS,DFS及其应用)(2)

    2)DFS 深度优先搜索总是对最近发现的节点v的出发边进行搜索,直到该节点的所有出发边都被发现 一旦节点v的所有出发边都被发现,搜索回溯到v的前驱结点进行 实现细节:时间戳 每一个结点有一个发现时间和 ...

  5. 算法系列之图--BFS

    广度优先搜索以源结点s为出发点,算法始终将已发现和未发现结点之间的边界,沿其广度方向向外扩展.也即算法需要在发现所有距离源结点s为k的所有结点之后才会去发现距离源结点距离为k+1的其他结点. talk ...

  6. 图的 储存 深度优先(DFS)广度优先(BFS)遍历

    图遍历的概念: 从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历(Traversing Graph).图的遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础.图的 ...

  7. 【Python算法】遍历(Traversal)、深度优先(DFS)、广度优先(BFS)

    图结构: 非常强大的结构化思维(或数学)模型.如果您能用图的处理方式来规范化某个问题,即使这个问题本身看上去并不像个图问题,也能使您离解决问题更进一步. 在众多图算法中,我们常会用到一种非常实用的思维 ...

  8. 大数据技术之_19_Spark学习_05_Spark GraphX 应用解析 + Spark GraphX 概述、解析 + 计算模式 + Pregel API + 图算法参考代码 + PageRank 实例

    第1章 Spark GraphX 概述1.1 什么是 Spark GraphX1.2 弹性分布式属性图1.3 运行图计算程序第2章 Spark GraphX 解析2.1 存储模式2.1.1 图存储模式 ...

  9. 判断图连通的三种方法——dfs,bfs,并查集

    Description 如果无向图G每对顶点v和w都有从v到w的路径,那么称无向图G是连通的.现在给定一张无向图,判断它是否是连通的. Input 第一行有2个整数n和m(0 < n,m < ...

  10. Day1 BFS算法的学习和训练

    ​ 因为自己的原因,之前没有坚持做算法的相应学习,总是觉得太难就半途而废,真的算是一个遗憾了,所以现在开始,定一个30天入门学习算法计划. ​ 我是根据<算法图解>的顺序进行安排的,自己对 ...

随机推荐

  1. wake on lan sender 2.0.8

    局域网 远程关机

  2. 如何获取android环境自带的jar包

    首先找到你需要用到的类,Ctrl 并点击跳转到这个类 跳转过来之后,找到这个类所在的包 Ctrl并点击,此时会跳转到这个包所在的jar的位置 右键class.jar并选择在文件资源浏览器打开 打开以后 ...

  3. Vue项目的打包方式(生成dist文件)

    一.相关配置情况一(使用的工具是 vue-cil) 如果是用 vue-cli 创建的项目,则项目目录中没有 config 文件夹,所以我们需要自建一个配置文件:在根目录 src 下创建文件 vue.c ...

  4. Iframe 默认高度、宽度

    项目中还在使用 Iframe ,一次看代码时发现 Iframe 没有指定高度.宽度,可是在页面上显示的时候却有高度.宽度.想着应该是 Iframe 的默认值,于是写了一个简单的页面,代码如下: 1 & ...

  5. sos 扩展命令文档

    https://learn.microsoft.com/zh-cn/dotnet/framework/tools/sos-dll-sos-debugging-extension?redirectedf ...

  6. sql server 常用高级查询sql

    数据源:表:coursename kecheng fenshu张三 语文 81张三 数学 75李四 语文 76李四 数学 90王五 语文 81王五 数学 100王五 英语 90赵六 语文 88赵六 数 ...

  7. linux 服务器 重命名

    vim /etc/hosts 追加 10.10.134.68 RmcbTestDB3 RmcbTestDB3               # ip  名称 名称 127.0.0.1 localhost ...

  8. Python学习笔记文件读写之生成随机的测试试卷文件

    随笔记录方便自己和同路人查阅. #------------------------------------------------我是可耻的分割线--------------------------- ...

  9. redis常用命令之Hash

    redis常用命令之Hash Hash常用命令 redis 可以理解为一个全局的大字典,key就是数据的唯一标识符.对应的key不同,value也不同.redis有5个基本的数据类型. 1 redis ...

  10. Blob下载

    下载方式 const aBlob = new Blob( array, options ); export function downLoadFile(data: ArrayBuffer, fileN ...