7算法设计与分析笔记(Authored by M.H Alsuwaiyel, Saudi)

第七章 图的遍历

  • 解决图的问题,大多数时候需要能够不重复的完全遍历每个节点,是求解问题的基础。
  • 和树的遍历类似,图的遍历希望从图的某个顶点出发遍历剩余所有顶点;但因为图可能形成环,在访问某顶点后可能有绕回该点。
  • 下面介绍两种最基本图的遍历算法:深度优先搜索(Dpeth-First Search, DFS)、广度优先搜索(Breadth-First Search, BFS。他们均适用于有向图、和无向图。

深度优先搜索DFS

  • 所谓深度,可以理解为一个人从起点找一条路出发一直前进,不碰壁不回头;回头后,再找一条新路径继续前进,直到所有位置都被访问过。

  • 例如,如下无向图

    假设起点为2DFS顺序为:

    2-1-0-3-4~or~2-3-0-1-4~or~2-4-0-1-3取决于从哪条路径先开始。

  • 深度优先搜索树:利用深度优先搜索得到的访问序列构成的树;

    假设从顶点a出发,得到的一种深度优先搜索树如下,顶点x(a,b)表示DFS的先序号、后序号,即第几个被访问的。

    • 注意当a-b-c-d-e不能继续前进时,DFS采用回退的方式,看d、c是否可以继续DFS;回退到b时,发现未被遍历的f,进而得到如下深度优先树;
  • (x,y)x表示前序(predfn第几个被访问),y表示后序(postdfn折返时第几个被重新访问);

    • 树边:DFS中,如果在探索(v,w)时,w是首次被访问,则边(v,w)为树边;
    • 回边:其他所有的边(\in E);
    • a-b-c-d-e后,e连接的d、c已经被访问,此时postdfn得以自增1
    • 折返到b时,仍然可以继续深度搜索,直到访问到jj回退postdfn=4

    对于有向图,前序、后序的概念相同,新增几个边的概念;

    • 树边:DFS在探索边(v,w)时,w是首次被访问的,则(v,w)是树边;
    • 回边:在迄今构建的深度优先搜索树,wv的祖先,且当探索(v,w)时顶点w已经被访问过,这样的边是回边;
    • 前向边:在迄今构建的深度优先搜索树,wv的子孙,且当探索(v,w)时顶点w已经被访问过,这样的边是回边;
    • 横跨边:其他所有的边。
    • 为验证自己画的边是否缺失或多余,可以将自己的树与图G中的边对比,应当是能够一一对应的。

    这里只列出了abfecd这种访问顺序。

DFS

输入:有向图或无向图G=(V, E)。

输出:在相应的深度优先搜索树中顶点的前序和后序。

  • 递归法
predfn <- 0; postdfn <- 0
for each v in V
    visited[v] <- false
end for
for each v in V
    if visited[v] = false then dfs(v)
end for
过程:dfs(v)
visited[v] <- true
predfn <- predfn + 1 #dfs开始时访问到某个结点,即可得到其前序
for each (v, w) in E
    if visited[w] = false then dfs(w)
end for
postdfn <- postdfn + 1 #折返时对postdfn进行赋值
  • 堆栈法(未进行前序后序记录

    1. 初始时,入栈起点;

    2. 每次出栈一个顶点并输出,将与其直接相连的顶点入栈;

    3. 重复执行第二步直到栈为空;

for each v in V
    visited[v] <- false
push(v, S) #S为堆栈
while S not empty
    v <- pop(S)
    visited[v] <- true
    output: v
    for each (v,w) in E
        if visited[w] = false then
            push(w, S)
        end if
    end for
end while

深度优先搜索的应用

图的无回路性

  • 回忆:什么是连通?图中的任一个顶点到其他顶点至少存在一条路径。

  • G=(V,E)是一个有n个顶点,m条边的有向或无向图。为了测试G是否存在回路,我们可以进行一次DFS,若出现回边(即访问过的顶点仍然要被if visited[v] = false判断),则存在回路否则不存在。

  • G是一个连通无向图,那么当且仅当m=n-1时,图变成一个树时,不存在回路。

拓扑排序

  • 定义:给定一个有向无回路图G=(V,E),找到一个这样的线性序列:对于相邻的ab,如果a排在b的前面,说明ab有一条边或者ab无联系。

  • 例如下图,

    • 每次选择入度为0的顶点a、b均可作为第一个选择的,以a为例:那么将a和它的边从图中删除,此时仅b的入度为0,再次选择b;此时c、d的入度都为0,选择d;此时仅c的入度为0,选择c······最后得到的序列为a~b~d~c~e~f~g
  • 为实现拓扑排序,可以对每个顶点增加入度、出度两个数据项并初始化。

    1. 初始化时,将入度为0的顶点入队;

    2. 从队列中取出一个顶点并输出,并更新与之相关顶点的入度,再次选择入度为0的顶点入队;

    3. 重复第二步直到队列为空;

    • 此算法只能输出一种拓扑排序(对于确定的图G=(V,E)可能存在多种拓扑排序);
  • 另一种利用深度优先算法,计数器postdfn定义了图G的反拓扑系列,我们只需要在DFSpostdfn自增时增加一个输出步骤,把输出结果反过来就是拓扑排序。

寻找图的关节点

  • 在多于两个顶点的无向图G=(V,E)中,存在一个顶点v,如果有不同于v的两个顶点u,w,在u,w间的任何路径都必定经过v则称v是关节点。
  • 为找到关节点,在图G上执行一个深度优先遍历,在遍历过程中,对每个顶点v维护两个标号:\alpha[v],\beta[v]\alpha[v]仅仅是predfn,对于\beta[v]初始化为\alpha[v],在后续遍历中国\beta[v]更新为下面几个值中的最小值:
    • \alpha[v]
    • \alpha[u]:对于每个顶点u(u,v)是一条回边;
    • \beta[w],在DFS过程中的每条边(v,w)
  • 关节点的确定如下:
    • 根是一个关节点,当且仅当在深度优先搜索树中,它有两个或更多的儿子;
    • 根以外的节点v是一个关节点当且仅当v有一个儿子w,满足\beta[w]\geq \alpha[v](只要存在一个就行)

ARTICPOINTS

输入:连通无向图G=(V,E)

输出:包含G的所有可能关节点数组A[1···count]

设s为起始顶点
for each v in V
    visited[v] <- false
end for
predfn <- 0; count <- 0; rootdegree <- 0
dfs(s)
过程: dfs(v)
visited[v] <- true; artpoint <- false; predfn <- predfn + 1
alpha[v] <- predfn; beta[v] <- alpha[v] #初始化alpha,beta
for each (v,w) in E
    if (v,w)是树边 then
        dfs(w)
        #下面的操作发生在w回退到v时
        if v = s then #如果是根节点,用rootdegree判断根节点是否有两个以上的儿子
            rootdegree <- rootdegree + 1
            if rootdegree = 2 then artpoint <- true
        else #不是根节点,则找最小值
            beta[v] <- min{beta[v], beta[w]}
            if beta[w] >= alpha[v] then artpoint <- true
        end if
    else if (v,w)是回边 then beta[v] <- min{beta[v], alpha[w]}
    else do noting
    end if
 end for
if artpoint then #记录关节点
    count <- count + 1
    A[count] <- v
end if
  • zGJxKK.png

  • 结合深度有限搜索树判断关节点

    1. 深度优先生成树的根是关节点的充要条件是它至少有两个子女;
    2. 任何其它顶点u是关节点的充要条件是u至少有一个子女w,使得经过只由w,w的后代以及一条回边构成的路径不可能到达u的祖先,因为删除顶点u及其关联的边将使w及其后代与u的祖先断开联系。

强连通分支

  • 如果一个有向图G=(V,E),强连通分支是它的顶点的一个极大子集,在该集中,任意两个顶点直接都存在一条路径。通俗地理解,把顶点看成一个房子,强连通分支集合里可以从任意一个房子走到另一个房子。

STRONGCONNECTCOMP

输入:有向图G=(V,E)。

输出:G中的强连通分支。

在图G执行深度优先搜索,对每个顶点赋给相应的postdfn。
颠倒图G中边的方向,构造新的图G'。
从具有最好postdfn的顶点开始,在G'上进行深度优先搜索,如果DFS不能访问所有顶点,则找次大的postdfn顶点开始DFS。
所得到的每一棵树都是一个强连通分支。

广度优先搜索BFS

  • 所谓广度,形象地理解为一圈一圈的访问,从起始点往外扩散,利用队列实现。

  • 对于BFS也有广度优先搜索树、树边、回边、前向边、横跨边

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 第五章 树和二叉树 树和二叉树的定义 1、树的定义 一种非线性结构。树是递归结构,在树的定义中又用到了树的概念。 ...
    游戏原画设计阅读 1,454评论 0 0
  • 线性表 1.顺序存储结构 线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里。是随机存取的顺序存储结构。顺序...
    你臭显摆什么呀阅读 3,595评论 0 0
  • 数据结构 some concepts 数据:所有能被输入到计算机中,且能被计算机处理的符号的集合。是计算机操作的对...
    liuzhangjie阅读 576评论 0 0
  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,802评论 0 13
  • 图遍历与回溯 图搜索->形成搜索树 穷举法。 贪心法。多步决策,每步选择使得构成一个问题的可能解,同时满足目标函数...
    北风知我意阅读 877评论 0 0