当前位置: 首页 > news >正文

数据结构——广度优先搜索

要实现图的“分层遍历”,广度优先搜索(BFS)是核心方法——它遵循“先访问离起始顶点近的顶点,再逐步向外扩散”的逻辑,像水波纹一样覆盖所有可达顶点。下面从思想、过程、实现和特点展开,结合图示详细讲解。

广度优先搜索

图的遍历需要按规则访问所有顶点,广度优先搜索(BFS)的核心是“分层探索、逐层扩散”,是探索图结构的另一种基础方法。

1. 广度优先搜索的基本思想

广度优先搜索的逻辑可以类比“洪水蔓延”:从起始顶点(洪水源头)出发,先淹没与源头直接相邻的所有顶点(第一层);再从这些顶点出发,淹没它们的邻接顶点(第二层);以此类推,直到所有可达顶点都被“淹没”(访问)。具体到图中,就是从起始顶点出发,先访问该顶点,再依次访问它的所有未访问邻接顶点;然后对这些邻接顶点,再依次访问它们的未访问邻接顶点,直到所有顶点都被访问。

2. BFS的遍历过程(结合图示分析)

以提供的广度优先搜索过程图为例,假设从顶点V1V_1V1开始遍历,整个过程可拆解为“分层访问”的阶段:

  • 第0层(起始层):访问V1V_1V1(标记为已访问),将其加入队列,作为遍历的起点。
  • 第1层(直接邻接层):从队列中取出V1V_1V1,访问其所有邻接顶点V2V_2V2V3V_3V3(标记为已访问),并将V2V_2V2V3V_3V3加入队列。
  • 第2层(次邻接层):从队列中取出V2V_2V2,访问其所有未访问邻接顶点V4V_4V4V5V_5V5(标记为已访问),并将V4V_4V4V5V_5V5加入队列;接着取出V3V_3V3,访问其所有未访问邻接顶点V6V_6V6V7V_7V7(标记为已访问),并将V6V_6V6V7V_7V7加入队列。
  • 第3层(更外层):从队列中取出V4V_4V4,访问其未访问邻接顶点V8V_8V8(标记为已访问),并将V8V_8V8加入队列;取出V5V_5V5,访问其邻接顶点(若有未访问的);取出V6V_6V6,访问其邻接顶点;取出V7V_7V7,访问其邻接顶点。
  • 第4层及后续:从队列中取出V8V_8V8,访问其邻接顶点V4V_4V4(已访问)、V5V_5V5(已访问)等,直到队列空,遍历结束。

图中顶点的层级关系清晰体现了“逐层扩散”的特点:V1V_1V1是第0层,V2、V3V_2、V_3V2V3是第1层,V4、V5、V6、V7V_4、V_5、V_6、V_7V4V5V6V7是第2层,V8V_8V8是第3层,严格遵循“先访问近的顶点,再访问远的顶点”的逻辑。

3. BFS的实现方式

BFS的实现依赖队列(先进先出的特性,保证“分层访问”的顺序),主要有“队列模拟”的非递归实现(递归实现不符合BFS的分层逻辑,一般不采用)。

(1)队列模拟的实现
以邻接表存储的图为例,代码框架如下(类C语言):

// 假设图的邻接表结构为:顶点数组+弧结点,visited数组标记顶点是否已访问
typedef struct {VNode vertices[MAX_VERTEX_NUM]; // 顶点数组int vexnum, arcnum;             // 顶点数和弧数
} Graph;void BFS(Graph G, int start, bool visited[]) {Queue Q;InitQueue(&Q);  // 初始化队列visited[start] = true; // 标记起始顶点为已访问EnQueue(&Q, start);    // 起始顶点入队printf("访问顶点:%d\n", start); // 访问顶点(可替换为业务操作)while (!QueueEmpty(Q)) {int v = DeQueue(&Q); // 取出队首顶点// 遍历v的所有邻接顶点,将未访问的入队并标记for (ArcNode *p = G.vertices[v].firstarc; p != NULL; p = p->nextarc) {int w = p->adjvex;if (!visited[w]) {visited[w] = true;EnQueue(&Q, w);printf("访问顶点:%d\n", w); // 访问邻接顶点}}}
}// 调用入口:初始化visited数组,处理非连通图(多个连通分量)
void BFSTraverse(Graph G) {bool visited[MAX_VERTEX_NUM] = {false}; // 初始化所有顶点为未访问for (int i = 0; i < G.vexnum; i++) {if (!visited[i]) {BFS(G, i, visited); // 对每个未访问的顶点,启动BFS}}
}

队列实现的核心是“先入队的顶点先处理,其邻接顶点后入队”,严格保证了“分层遍历”的顺序——同一层的顶点会在队列中集中处理,体现了BFS“广度优先”的特性。

4. BFS的复杂度与特点
  • 时间复杂度

    • 若图用邻接表存储,每个顶点和每条边都被访问一次,时间复杂度为O(n+e)O(n + e)O(n+e)nnn为顶点数,eee为边数);
    • 若图用邻接矩阵存储,需遍历每个顶点的所有邻接顶点,时间复杂度为O(n2)O(n^2)O(n2)
  • 空间复杂度
    主要消耗在队列上,最坏情况下(如完全图,起始顶点的邻接顶点数为n−1n-1n1)队列需存储n−1n-1n1个顶点,空间复杂度为O(n)O(n)O(n)

  • 核心特点

    • 能高效解决“无权图的最短路径”问题(因为是分层遍历,第一次访问某顶点时的路径就是最短路径);
    • 遍历路径不唯一(邻接顶点的选择顺序不同,遍历序列不同),但都遵循“分层扩散”的核心逻辑;
    • 仅能通过队列实现(递归无法体现分层逻辑),代码逻辑清晰,适合处理“按层探索”的场景。

综上,广度优先搜索通过“队列+分层扩散”的逻辑,实现了图的遍历,能高效解决无权图的最短路径等问题。结合图示的遍历过程,能直观理解“逐层访问、向外扩散”的执行逻辑,是图论中探索层次、最短路径的基础算法,为后续图的应用(如拓扑排序、最短路径算法)提供了遍历支撑。

http://www.dtcms.com/a/513310.html

相关文章:

  • 网站建设教程 作业黄冈黄页
  • 潍城区住房和城乡建设局网站网站怎么做中英文交互
  • 厨房电子秤方案:厨房秤常规的功能有那些?
  • 旅游景点网站模板大全哪家网站开发培训好
  • FontBook for mac字体管理工具
  • 网站聚合页面芙蓉区建设局网站
  • 美容店网站建设网站做海康直播
  • 网站如何做留言板mxd 主题Wordpress
  • 为什么里程碑设置不清晰会拖慢进度
  • 搭建影视网站wordpress修改登陆界面
  • php做企业网站需要多久模仿别人网站
  • 丰和园林建设集团网站wordpress模板结构
  • 推广网站建设做外贸一般看什么网站
  • 网站建站六个目标ip网站查询服务器
  • 【Java全栈项目定制开发】承接各类程序编写与系统开发任务
  • 【队列 + 宽搜(BFS)】4. 在每个树⾏中找最⼤值(medium)
  • 泰安有口碑的企业建站公司建设外贸网站的细节
  • 360免费建站软仵下载查看网站被恶意镜像
  • 一个人做网站时间展厅设计手绘图
  • 怎么做门淘宝网站开发公司的安全生产工作方案
  • 用asp.net做的网站有哪些企业网站建设中有哪几个重要点
  • [人工智能-大模型-31]:大模型应用层技术栈 - 智能决策层(AI Agent)
  • 东营网站推广排名旅游景区网站建设方案文档
  • 江苏国泰做的网站案例软件开发工具性能审计不包括
  • c语言精品课程网站开发wordpress上传功能
  • 多模态大模型真的需要原生分辨率吗?
  • Kafka 概念与部署手册
  • 计算某天是某年里的第几天
  • 网站外链收录很多 内链收录几个苏州网站建设哪家好
  • 为什么要建设门户网站中企动力科技股份有限公司佛山分公司