首页 > 其他分享 >从零开始学数据结构系列之第四章《 广度优先遍历BFS》

从零开始学数据结构系列之第四章《 广度优先遍历BFS》

时间:2024-07-05 11:30:42浏览次数:18  
标签:结点 遍历 第三章 BFS flag 从零开始 二叉树 顶点

文章目录


广度优先遍历(BFS)

概念

​   广度优先遍历(Breadth First Search),又称为广度优先搜索,简称BFS。

​   如果说图的深度优先遍历类似树的前序遍历,那么图的广度优先遍历就类似于树的层序遍历了。
​   广度优先搜索是一种分层的查找过程每向前走一步可能访问一批顶点,不像深度优先搜索那样有往回退的情况,因此它不是一个递归的算法。为了实现逐层的访问,算法必须借助一个辅助队列,以记忆正在访问的顶点的下一层顶点。

简单来说就类似于我们之前学的层次遍历

广度优先遍历算法步骤

  1. 访问初始结点 v 并标记结点 v 为已访问
  2. 结点 v 入队列
  3. 当队列非空时,继续执行,否则算法结束
  4. 出队列,取得头结点 u
  5. 查找结点 u 的第一个邻接结点 w
  6. 若结点 u 的邻接结点 w 不存在,则转到步骤 3;否则循环执行以下三个步骤
    1. 若结点 w 尚未被访问,则访问结点 w 并标记为已访问
    2. 结点 w 入队列
    3. 查找结点 u 的继 w 邻接结点后的下一个邻接结点 w,转到步骤6

我们用的是以下这张图:

在这里插入图片描述

总代码

/*
*	总体思路感觉与DFS差不多
*	基本就是层次遍历的思想 + DFS写法内容
*/
void BFS(Graph* G, int* visited, int index) 
{
	int j = 0;
	int i = 0;
    Queue* Q = initQueue();
    printf("%c ", G -> vexs[index]);
    visited[index] = 1;
    enQueue(Q, index);
    while (!isEmpty(Q)) 
	{
        i = deQueue(Q);
        for (j = 0; j < G -> vexNum; j++) 
		{
            if (G -> arcs[i][j] && !visited[j]) 
			{
                printf("%c ", G -> vexs[j]);
                visited[j] = 1;
                enQueue(Q, j);
            }
        }
    }
}

遍历过程如下:

  <1>先输出顶点A,此时flag[0]=1,表示第一列(j=0)已经有顶点A输出,这里保证每个顶点都输出的话,就要做这个标记,之后就不会再来这一列(j=0)找顶点了

i\j→(j)01234
↓(i)<1>ABCDE
0A0 flag[0]=11110
1B10111
2C11000
3D11001
4E01010

  <2>输出顶点A后,继续在A行里面找1,B,C,D都有1,所以顶点都输出,并将其顶点对应的下标j值存入队列中,之后会访问这些j下标的行。另外还flag[1]=flag[2]=flag[3]=1,标志着BCD列都没有顶点输出了。

i\j→(j)01234
↓(i)<2>ABCDE
0A0 flag[0]=11flag[1]=11flag[2]=11flag[3]=10
1B10111
2C11000
3D11001
4E01010

**<3>**之后出队的是1,i=1,就来到了B行,B中ABCD列顶点都标记输出过了,E列有1,未标记,表示有边,输出E,之后j=4这个下标入队。到C行之后每一行就没有顶点了输出,因为列全标记了,遍历才结束。

i\j→(j)01234
↓(i)<3>ABCDE
0A0 flag[0]=11flag[1]=11flag[2]=11flag[3]=10
1B10111flag[4]=1
2C11000
3D11001
4E01010

总结:

​   flag是用来标记列的,可以这样认为:一列代表一个顶点,要是全部的列标记了就可以证明遍历结束了。另外,行只是用来看是否有到达下一个顶点的条件(有1就有边),这里行的执行顺序是按入队出队顺序决定的。

往期回顾

1.【第一章】《线性表与顺序表》
2.【第一章】《单链表》
3.【第一章】《单链表的介绍》
4.【第一章】《单链表的基本操作》
5.【第一章】《单链表循环》
6.【第一章】《双链表》
7.【第一章】《双链表循环》
8.【第二章】《栈》
9.【第二章】《队》
10.【第二章】《字符串暴力匹配》
11.【第二章】《字符串kmp匹配》
12.【第三章】《树的基础概念》
13.【第三章】《二叉树的存储结构》
14.【第三章】《二叉树链式结构及实现1》
15.【第三章】《二叉树链式结构及实现2》
16.【第三章】《二叉树链式结构及实现3》
17.【第三章】《二叉树链式结构及实现4》
18.【第三章】《二叉树链式结构及实现5》
19.【第三章】《中序线索二叉树理论部分》
20.【第三章】《中序线索二叉树代码初始化及创树》
21.【第三章】《中序线索二叉树线索化及总代码》
22【第三章】《先序线索二叉树理论及线索化》
23【第三章】《先序线索二叉树查找及总代码》
24【第三章】《后续线索二叉树线索化理论》
25【第三章】《后续线索二叉树总代码部分》
26【第三章】《二叉排序树基础了解》
27【第三章】《二叉排序树代码部分》
28【第三章】《二叉排序树代码部分》
29【第三章】《平衡二叉树基础概念》
30【第三章】《平衡二叉树的平衡因子》
31【第三章】《平衡二叉树的旋转基础详解》
32【第三章】《平衡二叉树的旋转类型图文详解》
33【第三章】《平衡二叉树的旋转类型总结及总代码》
34【第三章】《哈夫曼树简单了解》
35【第三章】《哈夫曼树的构造方法》
36【第三章】《哈夫曼编码构造及代码》
37【第三章】《图的定义》
38【第三章】《图的基本概念和术语》
39【第三章】《图的存储结构》
40【第三章】《图的遍历之深度优先遍历》

标签:结点,遍历,第三章,BFS,flag,从零开始,二叉树,顶点
From: https://blog.csdn.net/qq_62548908/article/details/140189360

相关文章

  • 从零开始学习嵌入式——C语言数值传递(值传递和地址传递)
        C语言实现主函数与被调用子函数变量之间数值交换的方法。 1、值传递:主函数中的数值并未实现交换。2、地址传递:交换的是指针指向,a,b并未实现交换 3、传递地址,交换地址实现值的交换 4、传入地址,定义的子函数 知道了主函数传递的地址参数才能对主函数当中......
  • powershell遍历文件夹压缩以及编写生成k3配置
    Add-Type-AssemblyNameSystem.IO.CompressionAdd-Type-AssemblyNameSystem.IO.Compression.FileSystem#设置源文件夹和目标日志文件的路径$sourceFolder="C:\myapp\bin"$destFolder="C:\myapp\OutPut\"$logFilePath="C:\myapp\log.x......
  • C#实现DFS和BFS
    以图示为例:Noderoot=newNode("A",newNode("B",newNode("C"),newNode("D")),newNode("E",newNode("F"),newNode("......
  • 从零开始学习数据结构--2.1线性表之顺序表
    到这一章线性表,我们要掌握的就多了。1.线性表的定义线性表是n个具有相同特性的数据元素的有限序列。我们可以理解为幼儿园排队,在幼儿园里面,每个小朋友都是有一定的序号的,小朋友可以领到他们的专属号码,比如说小明是一号,小花是二号......那么,我们就可以说幼儿园小朋友排队属于......
  • 每日一题:Leetcode-102 二叉树的层序遍历
    力扣题目解题思路java代码力扣题目:给你二叉树的根节点 root ,返回其节点值的 层序遍历 。(即逐层地,从左到右访问所有节点)。示例1:输入:root=[3,9,20,null,null,15,7]输出:[[3],[9,20],[15,7]]示例2:输入:root=[1]输出:[[1]]示例3:输入:root=[]输出:[]......
  • 从零开始的Django+vue项目实战(1)
    Introduction这个系列的blog是为哈工大(威海)的企业与服务智能计算研究中心(ICES)的纳新培训任务准备的,但是也适合想学习django并快速上手项目的友友。我们培训的目的要使新人学会web前后端开发。培训PPT里给出了用springboot和vue3来实现,但是如今django也愈发流行,为了弥补P......
  • 在Java中,Map 接口的实现(如 HashMap,LinkedHashMap,TreeMap 等)并不保证遍历 keySet() 或
    在Java中,Map接口的实现(如HashMap,LinkedHashMap,TreeMap等)并不保证遍历keySet()或entrySet()时的顺序。但是,某些特定的Map实现确实提供了特定的遍历顺序。1、HashMap:它基于哈希表实现,并不保证映射的顺序,特别是遍历顺序。因此,当你使用map.keySet()遍历HashMap时,结果可......
  • 教你从零开始制作一个Web蜜罐扫描器
    01想法的来源在渗透的过程中,会遇到很多蜜罐,一旦不小心踩了蜜罐,就会被溯源,所以很可怕。为了规避上面的现象,就需要把蜜罐筛出来。使用场景是在前期资产收集的过程中,搞到了一堆子域名,先筛掉一批蜜罐,留下可以攻击的纯净资产。同上得到的一份资产如下:如上图所示,大量的域名如......
  • 12.优化算法之队列+宽搜(BFS)
    BFS——广度优先算法(BreadthFirstSearch)-CSDN博客1.N叉树的层序遍历(广度优先搜索)429.N叉树的层序遍历-力扣(LeetCode)classSolution{publicList<List<Integer>>levelOrder(Noderoot){List<List<Integer>>ret=newLinkedList<>();......
  • 从零开始带你上手体验Sermant自定义插件开发
    本文分享自华为云社区《Sermant自定义插件开发上手体验》,作者:华为云开源。一、研究缘由由于目前我们所处的行业是汽车行业,项目上进行云服务的迁移时使用到了Sermant中的相关插件,为了加深对Sermant开发和运行机制的了解,我们从零开始体验Sermant自定义插件的开发。下面我们就Se......