图算法之BFS
深度优先搜索(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的更多相关文章
- 图算法(一)——基本图算法(BFS,DFS及其应用)(1)
1)BFS 广度优先搜索:给定源节点s,生成广度优先搜索树广度优先搜索树中从节点s到节点v的简单路径对应的就是s到v的最短路径(边数最少的路径)广度优先:将已发现节点与未发现节点之间的边界(灰色节点) ...
- 经典图算法Java代码实践:BFS,DFS以及几种最短路径算法
public class City { String name; int id; static int idCounter = 0; public City(String name) { this.n ...
- 程序员的算法课(18)-常用的图算法:广度优先(BFS)
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...
- 图算法(一)——基本图算法(BFS,DFS及其应用)(2)
2)DFS 深度优先搜索总是对最近发现的节点v的出发边进行搜索,直到该节点的所有出发边都被发现 一旦节点v的所有出发边都被发现,搜索回溯到v的前驱结点进行 实现细节:时间戳 每一个结点有一个发现时间和 ...
- 算法系列之图--BFS
广度优先搜索以源结点s为出发点,算法始终将已发现和未发现结点之间的边界,沿其广度方向向外扩展.也即算法需要在发现所有距离源结点s为k的所有结点之后才会去发现距离源结点距离为k+1的其他结点. talk ...
- 图的 储存 深度优先(DFS)广度优先(BFS)遍历
图遍历的概念: 从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历(Traversing Graph).图的遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础.图的 ...
- 【Python算法】遍历(Traversal)、深度优先(DFS)、广度优先(BFS)
图结构: 非常强大的结构化思维(或数学)模型.如果您能用图的处理方式来规范化某个问题,即使这个问题本身看上去并不像个图问题,也能使您离解决问题更进一步. 在众多图算法中,我们常会用到一种非常实用的思维 ...
- 大数据技术之_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 图存储模式 ...
- 判断图连通的三种方法——dfs,bfs,并查集
Description 如果无向图G每对顶点v和w都有从v到w的路径,那么称无向图G是连通的.现在给定一张无向图,判断它是否是连通的. Input 第一行有2个整数n和m(0 < n,m < ...
- Day1 BFS算法的学习和训练
因为自己的原因,之前没有坚持做算法的相应学习,总是觉得太难就半途而废,真的算是一个遗憾了,所以现在开始,定一个30天入门学习算法计划. 我是根据<算法图解>的顺序进行安排的,自己对 ...
随机推荐
- 家里静态Ip设置
分配的网段是10.10.1.*
- Qt事件处理的几种方式
Qt提供了5种事件处理和事件过滤的方法: 1.重写事件处理器函数 这是大部分情况最常用的一种,如重写 paintEvent().mousePressEvent().keyPressEvent() 等事 ...
- C#封装以及访问修饰符
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中".在面向对象程序设计方法论中,封装是为了防止对实现细节的访问. 抽象和封装是面向对象程序设计的相关特性.抽象允许相关 ...
- antd Vue--this.$confirm弹窗使用
看API中this.$confirm弹窗使用不对 讲的也不明确,在此记录下正确的用法 this.$confirm("确认删除文件?",{ type:'error'}).then(( ...
- Java本地缓存解决方案---使用Google的CacheBuilder
一.背景 当业务实现上需要用到本地缓存,来解决一些数据量相对较小但是频繁访问数据的场景,可以采用Google的CacheBuilder解决方案. 二.代码实现 1. 首先在maven中引入下面的包 & ...
- MySQL 常用命令(3)------表基本操作
五.表的基本操作 1.创建表 语法:create table <表名> ( <字段名1> <类型1> [,..<字段名n> <类型n>]); ...
- Ubuntu 20.04 部署kubernetes 网络组件calico-v3.2.1
1.官方网址: https://projectcalico.docs.tigera.io/archive/v3.21/getting-started/kubernetes/self-managed-o ...
- c#在代码中再次调用按钮点击事件
在一个按钮事件中调用另一个按钮(button1)的点击事件,可以直接如下: button1.PerformClick() 也称之为 以编程方式调用按钮的click事件
- 第一课 Markdown 实操
1.Markdown (#加空格) 二级标题 (##加空格) 三级标题 (###加空格) 四级标题 (####加空格) 2.字体 Hello world 加粗(字体2边加**) Hello world ...
- 在Unity3D中开发的Rim Shader
Swordmaster Rim Shaders 特点 本资源包共包含两种Rim效果的Shader (1)Rim Bumped Specular. (2)Rim StandardPBR(Metallic ...