图算法之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天入门学习算法计划. 我是根据<算法图解>的顺序进行安排的,自己对 ...
随机推荐
- 如何从相机拍照建立的Fileprovider中获取绝对路径
我们通过高版本获取的fileprovider,然后拍了个照片,如下 imageUri = FileProvider.getUriForFile 但是我们发现当我们 File file = new Fi ...
- Linux的stat命令结果说明
There are 3 kind of "timestamps": Access - the last time the file was read Modify - the la ...
- Rocky linux command-1
在Linux下一切皆文件 everything is file,包括目录也是文件的一种而这些文件被分为七种类型: • -:普通文件 • d: 目录文件 • b: 块设备 • c: 字符设备 • l: ...
- C++之split字符串分割
在C++中没有直接对应的split函数,字符串分割可借助以下方法实现: 1.借助strtok函数 函数原型:char * strtok (char *str, char * delim); 函数功能: ...
- 个人常用的win7快捷键
1.Win + D – 显示桌面 2.Win+L 锁定系统 3.Win + R – 打开运行窗口 4.Win+M 最小化所有窗口 当按下后当前所有窗口全都最小化.再次按下这个组 ...
- C# Visual Studio等,学习地址
Visual Studio 2022 学习地址 Visual Studio系列学习地址 Csharp11 学习地址 Csharp 学习地址 W3School公营,推广技术,免费学习 W3CSchool ...
- 查看Linux系统的一些信息
1.查看物理cpu个数 grep 'physical id' /proc/cpuinfo | sort -u | wc -l cat /proc/cpuinfo | grep "physic ...
- mac SIP系统完整性保护关闭方法
许多Mac用户反应,装了部分软件后打不开,那可能是sip系统完整性没有关闭.下面我们就来看一下如何关闭sip系统完整性. 检查状态 在sip系统完整性关闭前,我们先检查是否启用了SIP系统完整性保护. ...
- go实现ls
package mainimport ( "fmt" "log" "os")func main () { f,err :=os.Open(& ...
- C# 屏蔽词过滤
参考:https://www.cnblogs.com/kubidemanong/p/10834993.html public class TreeNode { public char Char; pu ...