当前课程知识点:数据结构(上) >  第六章 图 >  (d)深度优先搜索 >  06D-5 有向图

返回《数据结构(上)》慕课在线视频课程列表

06D-5 有向图在线视频

06D-5 有向图

下一节:06D-6 多可达域

返回《数据结构(上)》慕课在线视频列表

06D-5 有向图课程教案、知识点、字幕

相对于无向图

有向图的深度优先搜索要更为复杂

所涉及的情况也会更多

我们不妨来看这样一个实例

首先确认这是一幅有向图

在这个图中

我们将每一个顶点

都绘制成长方形

顶点的标识居中

在它的左右空白处 我们将分别

记录下它在遍历过程中

所获得的dTime和fTime两个时间标签

因此如果起点是A的话

它将在dTime等于1 也就是第一秒的时刻

被发现

同样 我们将它转为大写

并且将这个边框加粗 以示区别

以下从顶点 a 出发

经过一条有向边

我们可以在第二秒发现

并访问顶点B

同样地 我们将它变为大写

并加粗边框 以示区别

而此时处于DISCOVERED状态的顶点a

也需要以双线边框

与其它顶点相区别

以下从顶点b出发

又可以经过一条有向边

在第三秒发现并且处理顶点c

虽然从表面看顶点 c

存在若干条邻边

但是因为这里是有向图

实际上从c并没有发出

任何有效的边

因此在顶点c处

我们不得不做一次回溯

同样地 逆向经过刚才那条树边

回到顶点B

不要忘了 在此前我们需要为这个

已经访问结束的顶点c

记下它的fTime时间标签

也就是3+1等于4

再以下

同样地 顶点b在接过控制权之后

也会发现它的所有的邻居都已扫描

并且处理完毕

因此会继续沿着它所对应的那条树边

逆向地抵达它的父亲节点 也就是A

同样 顶点b访问结束的时刻

是4+1 也就是5

在顶点A再次地获得了控制权之后

它会继续刚才没有做完的事情

也就是继续扫描

它的其它邻接顶点

比如这里的顶点c 请注意

这是我们第一次遇到的一个情况

它的特征是我们立足当前的顶点

会发现它有一个邻居已经处于最终的

VISITED状态

已经访问完毕了

你应该还记得我们所设计的算法

在这种情况下 我们应该进而

分两种子情况来进行讨论

而区分的准则

就是dTime 时间标签

具体来说 要看当前节点A

与它的邻居节点c

谁的时间标签更小

或者等价地 谁更早被发现

如果像这种情况所示的那样

我们可以看到 1小于3

这就说明 顶点A相对于它的邻居c

是更早被发现的

因此根据算法的规则

我们应该将它们之间的那条有向边

归类为FORWARD

什么意思呢? 向前边

我想通过这个例子 你应该能够

很好地理解为什么叫向前边

没错 它的意思是说这条边

是由遍历树中的祖先节点向前

指向它的后代

所以称作FORWARD EDGE

是再形象和合适不过的了

再以下 顶点A还有一个邻居f

处于UNDISCOVERED的状态

这也就是为什么在接下来的第六秒

顶点F将接过控制权

此后呢 它将在第7秒将控制权交给

它的下一个邻居 也就是顶点G

现在我们立足于顶点G

也同样要去环顾四周

逐一地考察它的邻居们

我们可以看到 第一个邻居是顶点a

请注意 此时应该属于算法的第二种情况

这个邻居当前处于第二种状态

也就是DISCOVERED

根据算法的规则

我们应该将它们之间的

这条有向边

归类为BACKWARD

后向边或者叫回边

我们也该来体会一下为什么叫回边

你应该能看出来

其实它等效于在遍历树中

我们试图从一个后代

去回连到它的祖先

所以称之为BACKWARD

是再形象不过的了

同样地 一旦出现BACKWARD边

也就同时意味着我们发现了

至少一条回路

这样一个性质的严格证明

大家可以参考我们的教材

以及习题解析

好 再接下来 我们依然立足于

当前的顶点G

考察它的下一个邻居 也就是顶点c

当然 因为我们的状态变化是不可逆的

所以c自然依然处于

最终的VISITED状态

也就是说 我们又再次地遇到了

算法的第三种情况

同样 我们需要比较它们的

dTime时间标签

从而进一步地明确

此时到底是属于

两种子情况中的哪一种

不难看出 7要大于3

而不像此前1小于3

所以此时应该是处于

第三种情况中的

后一种子情况

你应该还记得

按照我们所设计的算法规则

此时应该将从当前顶点通往它邻居的

那条连边 归入CROSS一类

也就是跨边 跨越边

为什么称作是跨越边呢?

我们不难看出 在整个遍历树中

这两个顶点之间

并没有任何的祖先或后代的

直系血缘关系

如果要形象比喻的话

它们只不过是姑表亲

这样一类连接于姑表亲顶点之间的边

首先不应该称作是FORWARD边

其次也不应该称作是BACKWARD边

而称作跨越边

则是再形象和合适不过的了

至此 g的所有邻居

都已扫描并且处理完毕

因此对它的访问也应随即终止

所以它会在第八秒

记录下它的fTime时间标签

并且逆向地回退到它的父节点

也就是F

而此时的F顶点呢 所有的邻居

也都处理完毕

因此它依然需要回溯

同样 在回溯之前

也需要记下它的fTime时间标签

也就是8+1=9

最终的控制权

又再次地回到顶点A的手中

此时的顶点a

所有的邻接顶点也都扫描

并且处理完毕

所以也轮到它结束自己的遍历过程

它的fTime时间标签

应该是9再加1

也就是10

综观整个过程

我们总共用了10秒

遍历完了由这五个顶点所构成的

一个子图

更确切地讲 它们构成了

在这个图中 从顶点a出发

可以达到的区域

也称作可达区域

那么图中的其余部分呢?

比如说这里的顶点d以及e呢?

数据结构(上)课程列表:

第零章

-选课之前

--写在选课之前

--宣传片

-考核方式

--考核方式

-OJ系统说明

--关于OJ

--1-注册与登录

--2-界面与选课

--3-提交测试

-关于课程教材与讲义

--课程教材与讲义

-关于讨论区

--关于讨论区

-微信平台

--html

-PA晋级申请

--PA晋级

--MOOC --> THU 晋级申请专区

--THU --> CST 晋级申请专区

--编程作业不过瘾?且来清华试比高!

第一章 绪论(上)

-(a)计算

--01-A-1: 计算

--01a-2: 绳索计算机

--01a-3: 尺规计算机

--01a-4: 算法

--01a-5 : 有穷性

--演示

--01a-6 : 好算法

--(a)计算--作业

-(b)计算模型

--01b-1: 性能测度

--01b-2: 问题规模

--01b-3: 最坏情况

--01b-4: 理想模型

--01b-5: 图灵机

--01b-6: 图灵机实例

--01b-7: RAM模型

--01b-8: RAM实例

-(b)计算模型--作业

-(c)大O记号

--01c-1: 主流长远

--01c-2: 大O记号

--01c-3: 高效解

--01c-4 : 有效解

--01c-5 : 难解

--01c-6: 2−Subset

--01c-7: 增长速度

-(c)大O记号--作业

第一章 绪论(下)

-(d)算法分析

--01d-1: 算法分析

--01d-2: 级数

--01d-3: 循环

--01d-4: 实例:非极端元素+起泡排序

--01d-5: 正确性的证明

--01d-6: 封底估算-1

--01d-7: 封底估算-2

-(d)算法分析--作业

-(e)迭代与递归

--01-E-1: 迭代与递归

--01-E-2: 减而治之

--01-E-3: 递归跟踪

--01-E-4: 递推方程

--01-E-5: 数组倒置

--01-E-6: 分而治之

--01-E-7: 二分递归:数组求和

--01E-8 二分递归:Max2

--01E-09: Max2:二分递归

-(e)迭代与递归--作业

-(xc)动态规划

--01XC-1: 动态规划

--01XC-2: Fib():递推方程

--01XC-3: Fib():封底估算

--01XC-4: Fib():递归跟踪

--01XC-5: Fib():迭代

--01XC-6: 最长公共子序列

-- 演示

--01XC-7: LCS:递归

--01XC-8: LCS:理解

--01XC-9: LCS:复杂度

--01XC-A: LCS:动态规划

-(xc)动态规划--作业

-本章测验--作业

第二章 向量(上)

-(a)接口与实现

--02A-1 接口与实现

--02A-2 向量ADT

--02A-3 接口操作实例

--02A-4 构造与析构

--02A-5 复制

-(a)接口与实现--作业

-(b)可扩充向量

--02B-1 可扩充向量

--02B-2 动态空间管理

--02B-3 递增式扩容

--02B-4 加倍式扩容

--02B-5 分摊复杂度

-(b)可扩充向量--作业

-(c)无序向量

--02C-1 概述

--02C-2: 循秩访问

--02C-3 插入

--02C-4 区间删除

--02C-5 单元素删除

--02C-6 查找

--02C-7 唯一化

--02C-8 遍历

-(c)无序向量--作业

-(d1)有序向量:唯一化

--02D1-1 有序性

--02D1-2 唯一化(低效版)

--02D1-3 复杂度(低效版)

--02D1-4 唯一化(高效版)

--02D1-5 实例与分析(高效版)

-(d1)有序向量:唯一化--作业

-(d2)有序向量:二分查找

--02D2-1 概述

--02D2-2 接口

--02D2-3 语义

--02D2-4 原理

--02D2-5 实现

--02D2-6 实例

--02D2-7 查找长度

-(d2)有序向量:二分查找--作业

第二章 向量(下)

-(d3)有序向量:Fibonacci查找

--02D3-1 构思

--02D3-2 实现

--02D3-3 实例

--02D3-4 最优性

-(d3)有序向量:Fibonacci查找--作业

-(d4)有序向量:二分查找(改进)

--02D4-1 构思

--02D4-2 版本B

--02D4-3 语义

--02D4-4 版本C

--02D4-5 正确性

-(d4)有序向量:二分查找(改进)--作业

-(d5)有序向量:插值查找

--02D5-1 原理

--02D5-2 实例

--02D5-3 性能分析

--02D5-4 字宽折半

--02D5-5 综合对比

-第二章 向量(下)--(d5)有序向量:插值查找

-(e)起泡排序

--02 E-1 构思

--02E-2 改进

--02E-3 反例

--02E-4 再改进

--02E-5 综合评价

-(e)起泡排序--作业

-(f)归并排序

--02F-1 归并排序:构思

--02F-2 归并排序:主算法

--02F-3 二路归并:实例

--02F-4 二路归并:实现

--02F-5 二路归并:正确性

--02F-6 归并排序:性能分析

-(f)归并排序--作业

-本章测验--作业

第三章 列表

-(a)接口与实现

--03A-1 从静态到动态

--03A-2 从向量到列表

--03A-3 从秩到位置

--03A-4 实现

-(a)接口与实现--作业

-(b)无序列表

--03B-1 循秩访问

--03B-2 查找

--03B-3 插入与复制

--03B-4 删除与析构

--03B-5 唯一化

-(b)无序列表--作业

-(c)有序列表

--03C-1 唯一化·构思

--03C-2 唯一化·实现

--03C-3 查找

-(c)有序列表--作业

-(d)选择排序

--03D-1 构思

--03D-2 实例

--03D-3 实现

--03D-4 推敲

--03D-5 selectMax()

--03D-6 性能

-(d)选择排序--作业

-(e)插入排序

--03E-1 经验

--03E-2 构思

--03E-3 对比

--03E-4 实例

--03E-5 实现

--03E-6 性能分析

--03E-7 平均性能

--03E-8 逆序对

-(e)插入排序--作业

-(xd)习题辅导:LightHouse

--03X D 习题辅导:LightHouse

-本章测验--作业

第四章 栈与队列

- (a)栈接口与实现

--04A-1 栈

--04A-2 实例

--04A-3 实现

- (a)栈接口与实现--作业

-(c1)栈应用:进制转换

--04C1-1 应用

--04C1-2 算法

--04C1-3 实现

-第四章 栈与队列--(c1)栈应用:进制转换

-(c2)栈应用:括号匹配

--04C2-1 实例

--04C2-2 尝试

--04C2-3 构思

--04C2-4 实现

--04C2-5 反思

--04C2-6 拓展

-(c2)栈应用:括号匹配--作业

-(c3)栈应用:栈混洗

--04C3-1 混洗

--04C3-2 计数

--04C3-3 甄别

--04C3-4 算法

--04C3-5 括号

-第四章 栈与队列--(c3)栈应用:栈混洗

-(c4)栈应用:中缀表达式求值

--04C4-1 把玩

--04C4-2 构思

--04C4-3 实例

--04C4-4 算法框架

--04C4-5 算法细节

--04C4−6A 实例A

--04C4−6B 实例B

--04C4−6C 实例C

--04C4-6D 实例D

-(c4)栈应用:中缀表达式求值--作业

-(c5)栈应用:逆波兰表达式

--04C5-1 简化

--04C5-2 体验

--04C5-3 手工

--04C5-4 算法

-第四章 栈与队列--(c5)栈应用:逆波兰表达式

-(d)队列接口与实现

--04D-1 接口

--04D-2 实例

--04D-3 实现

-第四章 栈与队列--本章测验

第五章 二叉树

-(a)树

--05A-1 动机

--05A-2 应用

--05A-3 有根树

--05A-4 有序树

--05A-5 路径+环路

--05A-6 连通+无环

--05A-7 深度+层次

-(a)树--作业

-(b)树的表示

--05B-1 表示法

--05B-2 父亲

--05B-3 孩子

--05B-4 父亲+孩子

--05B-5 长子+兄弟

-第五章 二叉树--(b)树的表示

-(c)二叉树

--05C-1 二叉树

--05C-2 真二叉树

--05C-3 描述多叉树

-(c)二叉树--作业

-(d)二叉树实现

--05D-1 BinNode类

--05D-2 BinNode接口

--05D-3 BinTree类

--05D-4 高度更新

--05D-5 节点插入

-(d)二叉树实现--作业

-(e1)先序遍历

--05E1-1 转化策略

--05E1-2 遍历规则

--05E1-3 递归实现

--05E1-4 迭代实现(1)

--05E1-5 实例

--05E1-6 新思路

--05E1-7 新构思

--05E1-8 迭代实现(2)

--05E1-9 实例

-(e1)先序遍历--作业

-(e2)中序遍历

--05E2-1 递归

--05E2-2 观察

--05E2-3 思路

--05E2-4 构思

--05E2-5 实现

--05E2-6 实例

--05E2-7 分摊分析

-第五章 二叉树--(e2)中序遍历

-(e4)层次遍历

--05E4-1 次序

--05E4-2 实现

--05E4-3 实例

-第五章 二叉树--(e4)层次遍历

-(e5)重构

--05E5-1 遍历序列

--05E5-2 (先序|后序)+中序

--05E5-3 (先序+后序)x真

-(e5)重构--作业

-本章测验--作业

第六章 图

-(a)概述

--06A-1 邻接+关联

--06A-2 无向+有向

--06A-3 路径+环路

-(a)概述--作业

-(b1)邻接矩阵

--06B1-1 接口

--06B1-2 邻接矩阵+关联矩阵

--06B1-3 实例

--06B1-4 顶点和边

--06B1-5 邻接矩阵

--06B1-6 顶点静态操作

--06B1-7 边操作

--06B1-8 顶点动态操作

--06B1-9 综合评价

-(b1)邻接矩阵--作业

-(c)广度优先搜索

--06C-1 化繁为简

--06C-2 策略

--06C-3 实现

--06C-4 可能情况

--06C-5 实例

--06C-6 多连通

--06C-7 复杂度

--06C-8 最短路径

-(c)广度优先搜索--作业

-(d)深度优先搜索

--06D-1 算法

--06D-2 框架

--06D-3 细节

--06D-4 无向图

--06D-5 有向图

--06D-6 多可达域

--06D-7 嵌套引理

-(d)深度优先搜索--作业

-第六章 图--本章测验

06D-5 有向图笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。