数据结构--图的遍历 BFS

数据结构–图的遍历 BFS

树的广度优先遍历

从 1 结点进行 b f s bfs bfs的顺序:
【1】
【2】【3】【4】
【4】【6】【7】【8】

图的广度优先遍历

从 2 号点开始 b f s bfs bfs的顺序:
【2】
【1】【6】
【5】【3】【7】
【4】【8】

树 vs 图

不存在“回路”,搜索相邻的结点时,不可能搜到已经访问过的结点
树的⼴度优先遍历(层序遍历):
①若树⾮空,则根节点⼊队
②若队列⾮空,队头元素出队并访问,同时将该元素的孩⼦依次⼊队
③重复②直到队列为空

搜索相邻的顶点时,有可能搜到已经访问过的顶点

代码实现

⼴度优先遍历(Breadth-First-Search, BFS)要点:

  1. 找到与⼀个顶点相邻的所有顶点
  2. 标记哪些顶点被访问过
  3. 需要⼀个辅助队列
    •FirstNeighbor(G,x):求图G中顶点x的第⼀个邻接点,若有则返回顶点号。
    若x没有邻接点或图中不存在x,则返回-1。
    •NextNeighbor(G,x,y):假设图G中顶点y是顶点x的⼀个邻接点,返回除y之外
    顶点x的下⼀个邻接点的顶点号,若y是x的最后⼀个邻接点,则返回-1
bool visited[MAX_VERTEX_NUM];
//广度优先遍历
void BFS(Graph G, int v)
{
    //从顶点v出发,广度优先遍历图G
    visit(v);
    //访问初始顶点v
    visited[v] = TRUE;
    //对v做已访问标记
    Enqueue(Q, v);
    //顶点v入队列Q
    while(!isEmpty(Q))
    {
        DeQueue(Q, v);
        //顶点v出队列
        for(w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)) //检测v所有邻接点
            if(!visited[w]) //w为v的尚未访问的邻接顶点visit(w);//访问顶点W
            {
                visited[w] = TRUE; //对w做已访问标记EnQueue(Q,w);   //顶点w入队列
            }//if
    }//while
}

遍历序列的可变性

同⼀个图的邻接矩阵表示⽅式唯⼀,因此⼴度优先遍历序列唯⼀ \color{red}同⼀个图的邻接矩阵表示⽅式唯⼀,因此⼴度优先遍历序列唯⼀ 个图的邻接矩阵表示式唯,因此度优先遍历序列唯

同⼀个图邻接表表示⽅式不唯⼀,因此⼴度优先遍历序列不唯⼀ \color{red}同⼀个图邻接表表示⽅式不唯⼀,因此⼴度优先遍历序列不唯⼀ 个图邻接表表示式不唯,因此度优先遍历序列不唯

算法存在的问题

如果是⾮连通图,则⽆法遍历完所有结点

bool visited[MAX_VERTEX_NUM];
//广度优先遍历
void BFS(Graph G, int v)
{
    //从顶点v出发,广度优先遍历图G
    visit(v);
    //访问初始顶点v
    visited[v] = TRUE;
    //对v做已访问标记
    Enqueue(Q, v);
    //顶点v入队列Q
    while(!isEmpty(Q))
    {
        DeQueue(Q, v);
        //顶点v出队列
        for(w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)) //检测v所有邻接点
            if(!visited[w]) //w为v的尚未访问的邻接顶点visit(w);//访问顶点W
            {
                visited[w] = TRUE; //对w做已访问标记EnQueue(Q,w);   //顶点w入队列
            }//if
    }//while
}

BFS算法(Final版)

bool visited[MAX_VERTEX_NUM];
void BFSTraverse(Graph G)   //对图G进行广度优先遍历for(i=0;i<G.vexnum;++i)visited[i]=FALSE;InitQueue(Q);
{
    //访问标记数组初始化//初始化辅助队列Q//从0号顶点开始遍历
    for(i = 0; i < G.vexnum; ++i)if(!visited[i])BFS(G, i);
    //对每个连通分量调用一次BFS//vi未访问过,从vi开始BFS
}
//广度优先遍历
void BFS(Graph G, int v)
{
    //从顶点v出发,广度优先遍历图G
    visit(v);
    //访问初始顶点v
    visited[v] = TRUE;
    //对v做已访问标记
    Enqueue(Q, v);
    //顶点v入队列Q
    while(!isEmpty(Q))
    {
        DeQueue(Q, v);
        //顶点v出队列
        for(w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)) //检测v所有邻接点
            if(!visited[w])    //w为v的尚未访问的邻接顶点visit(w);//访问顶点w
            {
                visited[w] = TRUE; //对w做已访问标记EnQueue(Q,w);   //顶点w入队列
            }//if
    }//while
}

复杂度分析

空间复杂度:最坏情况,辅助队列⼤⼩为 O(|V|)

邻接矩阵 \color{red}邻接矩阵 邻接矩阵存储的图:
访问 |V| 个顶点需要O(|V|)的时间
查找每个顶点的邻接点都需要O(|V|)的时间,⽽总共有|V|个顶点
时间复杂度= O ( ∣ V ∣ 2 ) \color{red}O(|V|^2) O(V2)

邻接表 \color{red}邻接表 邻接表存储的图:
访问 |V| 个顶点需要O(|V|)的时间
查找各个顶点的邻接点共需要O(|E|)的时间,
时间复杂度= O ( ∣ V ∣ + ∣ E ∣ ) \color{red}O(|V|+|E|) O(V+E)

⼴度优先生成树

广度优先生成树(Breadth-First Search Tree)是一种图算法,用于以广度优先的方式遍历和生成图的树形结构。该算法从图中的一个起始节点开始,逐层遍历图中的节点,直到遍历完所有与起始节点可达的节点。

广度优先生成树的过程如下:

  1. 选择一个起始节点作为根节点,并将其标记为已访问。
  2. 将起始节点入队列。
  3. 从队列中取出一个节点作为当前节点。
  4. 遍历当前节点的所有邻接节点:
    • 如果邻接节点未被访问过,则将其标记为已访问,并将其加入队列。
    • 将当前节点与邻接节点之间的边添加到生成树中。
  5. 重复步骤3和步骤4,直到队列为空。

广度优先生成树的特点是,它按照节点的层级顺序生成树,即先生成根节点,然后生成与根节点相邻的节点,再生成与这些节点相邻的节点,依次类推。因此,生成的树形结构具有层级感,节点之间的距离相对较近。

广度优先生成树在图算法中有广泛应用,例如最短路径算法、网络分析、社交网络分析等。它能够帮助我们理解和分析图结构,了解节点之间的关系和层级结构。

⼴度优先生成森林

广度优先生成森林(Breadth-First Search Forest)是在一个连通图中进行广度优先搜索的结果,其中可能包含多个生成树。每个生成树都是从一个起始节点开始,通过广度优先搜索遍历图中的节点而形成的树状结构。

广度优先生成森林的过程与广度优先生成树类似,只是在遍历图的过程中,如果发现还有未访问的节点,就选择其中一个未访问的节点作为新的起始节点,继续生成一棵新的生成树。这样,通过多次广度优先搜索,可以生成多棵独立的生成树,组成一个森林。

广度优先生成森林的特点是,它可以同时生成多个以不同起始节点为根的生成树,这些生成树之间可能没有直接的连接。每个生成树都是从一个起始节点开始,按照广度优先的方式遍历与其可达的节点,形成一个独立的树形结构。

广度优先生成森林在图算法中也有广泛应用,特别是在处理非连通图时。通过生成森林,我们可以获得图中所有连通分量的结构信息,并且可以对每个连通分量进行进一步的分析和处理。广度优先生成森林可以帮助我们理解和分析图的整体结构,以及不同连通分量之间的关系。

对⾮连通图的⼴度优先遍历,可得到⼴度优先⽣成森林

知识回顾与重要考点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/42868.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT:人工智能语言模型的革命性进步

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

PHP后台登录功能单账号登录限制

PHP后台登录功能单账号登录限制 单账号登陆是什么第一步创建数据表第二步创建登录页面test2.html第三步创建登录提交test2.php第四步访问后台首页第五步演示 单账号登陆是什么 一个用户只能登录一个账号通常被称为单账号登录限制或单用户单账号限制。这意味着每个用户只能使用…

微服务一 实用篇 - 5.分布式搜索引擎(ElasticSearch基础)

《微服务一 实用篇 - 5.分布式搜索引擎&#xff08;ElasticSearch基础&#xff09;》 提示: 本材料只做个人学习参考,不作为系统的学习流程,请注意识别!!! 《微服务一 实用篇 - 5.分布式搜索引擎&#xff08;ElasticSearch基础&#xff09;》 《微服务一 实用篇 - 5.分布式搜索…

vue实现excel数据下载,后端提供的list由前端转excel并下载

前言,因为项目需求需要,我们需要把后端传来的list转成excel模板,并且下载下来) 之前有用的插件,但是会有少0的情况,如下 所以采用另一个项目用过的方法,最终完美实现效果,如下: 1,首先我们来看下后端提供的数据结构 2,具体前端代码如下 封装的组件,需要的同学直接copy就行(这…

ORACLE实时SQL监控视图

引言 实时的SQL监控&#xff08;Real Time SQL Monitoring&#xff09;是Oracle 11g的一个新特性&#xff0c;它是一项强大的工具&#xff0c;用于监视和分析正在执行的SQL语句的性能和执行计划。该功能允许我们实时地跟踪SQL查询的执行过程&#xff0c;以及了解其资源消耗、等…

PHP登陆/php登录--【强撸项目】

强撸项目系列总目录在000集 PHP要怎么学–【思维导图知识范围】 文章目录 本系列校训本项目使用技术 上效果图phpStudy 设置导数据库 项目目录如图&#xff1a;页面代码后台代码 这么丑的界面能忍&#xff1f;配套资源作业&#xff1a; 本系列校训 用免费公开视频&#xff0…

macOS 源码编译 Percona XtraBackup

percona-xtrabackup-2.4.28.tar.gz安装依赖 ╰─➤ brew install cmake ╰─➤ cmake --version cmake version 3.27.0brew 安装 ╰─➤ brew update╰─➤ brew search xtrabackup > Formulae percona-xtrabackup╰─➤ brew install percona-xtrabackup╰─➤ xtr…

投个 3D 冰壶,上班玩一玩

本篇文章将介绍如何使用物理引擎和图扑 3D 可视化技术来呈现冰壶运动的模拟。 Oimo.js 物理引擎 Oimo.js 是一个轻量级的物理引擎&#xff0c;它使用 JavaScript 语言编写&#xff0c;并且基于 OimoPhysics 引擎进行了改进和优化。Oimo.js 核心库只有 150K &#xff0c;专门用…

基于扩展(EKF)和无迹卡尔曼滤波(UKF)的电力系统动态状态估计

1 主要内容 该程序对应文章《Power System Dynamic State Estimation Using Extended and Unscented Kalman Filters》&#xff0c;电力系统状态的准确估计对于提高电力系统的可靠性、弹性、安全性和稳定性具有重要意义&#xff0c;虽然近年来测量设备和传输技术的发展大大降低…

2816. 判断子序列

题目链接&#xff1a; 自己的做法&#xff1a; #include <bits/stdc.h>using namespace std;const int N 1e5 10; int a[N], b[N]; int main() {int n, m;bool flag true;scanf("%d%d", &n, &m);for (int i 0; i < n; i) scanf("%d"…

【并发专题】阻塞队列BlockingQueue实战及其原理分析

目录 前置知识队列有界队列、无界队列Queue——队列在JAVA里面的接口 阻塞队列介绍BlockingQueue——阻塞队列在JAVA里面的接口阻塞队列的应用场景JUC包下的阻塞队列 课程内容*一、ArrayBlockingQueue基本介绍应用场景使用示例基本原理数据结构核心源码解析双指针与环形数组 *二…

内存的五大分区(自用水文)

1、堆区&#xff08;heap&#xff09;——由程序员分配和释放&#xff0c; 若程序员不释放&#xff0c;程序结束时一般由操作系统回收。注意它与数据结构中的堆是两回事 2、栈区&#xff08;stack&#xff09;——由编译器自动分配释放 &#xff0c;存放函数的参数值&#xff0…

Android图形系统之SurfaceFlinger/OpenGL/HWC/Gralloc/FrameBufer/ION/GPU等关系(十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【C++】多态案例— —计算器类

author&#xff1a;&Calton tag&#xff1a;C topic&#xff1a;【C】多态案例— —计算器类 website&#xff1a;黑马程序员C date&#xff1a;2023年7月23日 目录 多态概要 案例实现 原理剖析 多态概要 多态是C三大特性之一&#xff08;封装、继承、多态&#xff…

【SpringBoot项目】Tomcat started on port(s): 8080 (http) with context path ‘‘

运行程序后出现下面的错误&#xff0c;并且在postman中无法获取到数据 在idea中的错误显示的如下 本人的原因是忘记在Controller中忘记写&#xff01;&#xff01;&#xff01;&#xff01; RestController 如果你不是以下原因可以参考下面的文章&#xff1a; Initializing S…

在VSCode中实现Rust编程调试指南

在 VS Code 中调试 Rust&#xff1a;终极指南 在本教程中&#xff0c;您将学习如何使用 VS Code 调试 Rust。可用于使用 VS Code 调试 Rust 的操作。设置 VS Code 来调试 Rust Rust因其易用性、安全性和高性能而继续保持其作为最受欢迎的编程语言的地位。随着 Rust 的流行&…

MySQL 的 crash-safe浅谈

MySql执行流程 MySQL作为当下最流行的开源关系型数据库&#xff0c;有一个很关键和基本的能力&#xff0c;就是必须能够保证数据不会丢。那么在这个能力背后&#xff0c;MySQL是如何设计才能保证不管在什么时间崩溃&#xff0c;恢复后都能保证数据不会丢呢&#xff1f;有哪些…

【期末课程设计】学生成绩管理系统

因其独特&#xff0c;因其始终如一 文章目录 一、学生成绩管理系统介绍 二、学生成绩管理系统设计思路 三、源代码 1. test.c 2. Student Management System.c 3.Stu_System.c 4.Teacher.c 5.Student Management System.h 前言&#xff1a; 学生成绩管理系统含教师…

基于PySceneDetect的视频场景变换侦测与处理

剪映中集成了一个智能镜头分割的功能,其实是基于python的三方库PySceneDetect来实现的,主要用于对视频进行分析,寻找场景切换或剪辑。 不过一个一个处理起来比较麻烦,这里介绍一个python的三方库实现自动化批量处理。 文章目录 PySceneDetect主要功能特征PySceneDetect的安…

[golang gin框架] 40.Gin商城项目-微服务实战之Captcha验证码微服务

本次内容需要 gin框架基础知识, golang微服务基础知识才能更好理解 一.Captcha验证码功能引入 在前面,讲解了微服务的架构等,这里,来讲解前面商城项目的 Captcha验证码 微服务 ,captcha验证码功能在前台,后端 都要用到 ,可以把它 抽离出来 ,做成微服务功能 编辑 这个验证码功能…
最新文章