当前课程知识点:数据结构(上) > 第六章 图 > (c)广度优先搜索 > 06C-5 实例
以下我们就以这幅无向图为例
具体地了解
整个广度优先搜索的详细过程
请注意 这里首先引入了
一个初始为空的队列
我们的起点不妨取作s
按照算法的流程 首先令s入队
并且同时将它标记为discovered(误)的状态
在这里 我们依然用深色
来表示处于这种状态的顶点
接下来将逐一地枚举s的邻居
也就是a c和d
它们都是白色
也就是处于最初的undiscovered的状态
因此它们都会被取出并且归入队中
请注意 关于同一顶点的所有邻居
我们这里并没有定义一个优先次序
实际上 这并不是什么实质的问题
你完全可以根据自己的偏好
采用某种策略 甚至是随机的策略
比如这里不妨以它们的ID
也就是字母编号为序
同样地 在这些顶点依次入队的同时
它们也会从最初的undiscovered的状态
转化为discovered的状态
这也是为什么在这个时刻
它们会进而转为深色
每个邻居状态转化的同时
都会生成一条tree edge
好
在所有相关的tree edge悉数生成之后
s也就完成了它的历史使命
它将会被标记为visited 也就是最终的状态
相应地 在图中这个顶点
改为双边框的形式以示区别
接下来 应该是当前的队首节点a出队
我们可以看到 在a出队之后
也同样需要遍历它的所有的邻居
其中s是它的父亲 所以直接忽略掉
而c已经被发现 处于discovered状态
这种情况应该是属于算法的else那个分支
也就是说 对c不做任何处理
而是将由a通往c的这条边标记为CROSS
也就是跨边
再接下来 a的下一个邻居e
在当时仍处于最初的undiscovered状态
这是属于算法流程的if那个分支
所以令e入队并且同时转为discovered的状态
在图中变成深色
好 接下来
又该轮到新的队首顶点c出队
c出队之后也需要环顾四周
首先忽略掉它的父亲s
以及已处于visited状态的a
实质需要考虑的只有
仍处于最初undiscovered状态的顶点b
所以令b入队并且同时转为discovered的状态
至此既然c的所有邻居都已处理完毕
它也顺利地转入最终的visited的状态
接下来 新的队首节点d同样会出队
而且站在d的角度 环顾它的所有邻居
忽略掉它的父亲
唯一的邻居b已经入队 处于discovered的状态
所以在这里无需做任何实质操作
而只需将由d通往b的这条边
标记为跨边CROSS
同样在此之后 d也将顺利地转入
最终的visited的状态
算法的焦点又进而转至新的队首顶点e
再一次地 站在顶点e的角度
环顾它的所有邻居
忽略掉它的父亲a
另外两个邻居f和g
都是处于最初undiscovered的状态
所以这也是属于算法的if分支
因此令这两个新发现的邻居依次入队
并且同时标记为discovered的状态
此后
e自己也顺利地转入最终的visited状态
综观全局 你就会发现
此时已经没有任何顶点
依然处于最初的undiscovered状态
所以接下来只不过是一系列的过门
可能会标记出一些cross edge
但是不再会有新的tree edge生成
所以经过若干过门之后
最终必然会转入这个状态
也就是说
所有的顶点经过入队之后都已出队
而且相应地 都已转化为最终的visited状态
此时如果忽略掉所有的cross edge
那么剩下的tree edge就的确构成了一棵树
如果你对这个还看得不是很清楚
不妨把cross edge剔除掉
转入这样一种形式
整个遍历的最终产物是一棵遍历支撑树
至此
对这个性质和结论
你应该不存任何质疑了吧?
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)计算
--演示
--(a)计算--作业
-(b)计算模型
-(b)计算模型--作业
-(c)大O记号
-(c)大O记号--作业
-(d)算法分析
-(d)算法分析--作业
-(e)迭代与递归
-(e)迭代与递归--作业
-(xc)动态规划
-- 演示
-(xc)动态规划--作业
-本章测验--作业
-(a)接口与实现
--02A-5 复制
-(a)接口与实现--作业
-(b)可扩充向量
-(b)可扩充向量--作业
-(c)无序向量
--02C-1 概述
--02C-3 插入
--02C-6 查找
--02C-8 遍历
-(c)无序向量--作业
-(d1)有序向量:唯一化
-(d1)有序向量:唯一化--作业
-(d2)有序向量:二分查找
-(d2)有序向量:二分查找--作业
-(d3)有序向量:Fibonacci查找
-(d3)有序向量:Fibonacci查找--作业
-(d4)有序向量:二分查找(改进)
-(d4)有序向量:二分查找(改进)--作业
-(d5)有序向量:插值查找
-第二章 向量(下)--(d5)有序向量:插值查找
-(e)起泡排序
--02E-2 改进
--02E-3 反例
-(e)起泡排序--作业
-(f)归并排序
-(f)归并排序--作业
-本章测验--作业
-(a)接口与实现
--03A-4 实现
-(a)接口与实现--作业
-(b)无序列表
--03B-2 查找
-(b)无序列表--作业
-(c)有序列表
--03C-3 查找
-(c)有序列表--作业
-(d)选择排序
--03D-1 构思
--03D-2 实例
--03D-3 实现
--03D-4 推敲
--03D-6 性能
-(d)选择排序--作业
-(e)插入排序
--03E-1 经验
--03E-2 构思
--03E-3 对比
--03E-4 实例
--03E-5 实现
-(e)插入排序--作业
-(xd)习题辅导:LightHouse
-本章测验--作业
- (a)栈接口与实现
--04A-1 栈
--04A-2 实例
--04A-3 实现
- (a)栈接口与实现--作业
-(c1)栈应用:进制转换
-第四章 栈与队列--(c1)栈应用:进制转换
-(c2)栈应用:括号匹配
-(c2)栈应用:括号匹配--作业
-(c3)栈应用:栈混洗
-第四章 栈与队列--(c3)栈应用:栈混洗
-(c4)栈应用:中缀表达式求值
-(c4)栈应用:中缀表达式求值--作业
-(c5)栈应用:逆波兰表达式
-第四章 栈与队列--(c5)栈应用:逆波兰表达式
-(d)队列接口与实现
--04D-1 接口
--04D-2 实例
--04D-3 实现
-第四章 栈与队列--本章测验
-(a)树
--05A-1 动机
--05A-2 应用
-(a)树--作业
-(b)树的表示
--05B-2 父亲
--05B-3 孩子
-第五章 二叉树--(b)树的表示
-(c)二叉树
-(c)二叉树--作业
-(d)二叉树实现
-(d)二叉树实现--作业
-(e1)先序遍历
-(e1)先序遍历--作业
-(e2)中序遍历
-第五章 二叉树--(e2)中序遍历
-(e4)层次遍历
-第五章 二叉树--(e4)层次遍历
-(e5)重构
-(e5)重构--作业
-本章测验--作业
-(a)概述
-(a)概述--作业
-(b1)邻接矩阵
-(b1)邻接矩阵--作业
-(c)广度优先搜索
--06C-2 策略
--06C-3 实现
--06C-5 实例
-(c)广度优先搜索--作业
-(d)深度优先搜索
--06D-1 算法
--06D-2 框架
--06D-3 细节
-(d)深度优先搜索--作业
-第六章 图--本章测验