算法导论复习笔记.docx

上传人:b****6 文档编号:8036256 上传时间:2023-01-28 格式:DOCX 页数:8 大小:21.14KB
下载 相关 举报
算法导论复习笔记.docx_第1页
第1页 / 共8页
算法导论复习笔记.docx_第2页
第2页 / 共8页
算法导论复习笔记.docx_第3页
第3页 / 共8页
算法导论复习笔记.docx_第4页
第4页 / 共8页
算法导论复习笔记.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

算法导论复习笔记.docx

《算法导论复习笔记.docx》由会员分享,可在线阅读,更多相关《算法导论复习笔记.docx(8页珍藏版)》请在冰豆网上搜索。

算法导论复习笔记.docx

算法导论复习笔记

《算法导论》复习笔记

Chapter22基本图算法

有向图邻接链表,计算节点出度和入度的时间复杂度

O(V+E)

开一个degree[]数组,大小为结点个数,复杂度O(V);

遍历邻接链表,经过边uv时,计算出度degree[u]+=1,计算入度degree[v]+=1,复杂度O(E)

将一个多图变成等价无向图,用邻接链表表示,时间复杂度O(V+E)

多图是允许重复边和自循环边的图。

开一个bool数组mark[],大小为节点个数,初始化为false。

复杂度O(V)。

对每个顶点u的邻接链表,遍历,令v为u的边所指向的顶点;如果mark[v]=false,将uv加入新图,并将mark[v]设置为true;否则就跳过。

复杂度O(E)

再次遍历u的连边,将mark[v]初始化

整体复杂度O(V+E)

伪代码:

SOLVE(G,G’)

1foreachvetexu∈G

2foreachv∈[u]

3ifmark[v]==false

4mark[v]==true

5Addedge(G’,u,v)

6foreachv∈[u]

7mark[v]=false

图G的邻接矩阵表示,给出一个O(V)的算法来判断有向图G中是否存在一个通用汇点。

通用汇点指的是入度|V|-1,但出度为0。

等价问题:

给定有向图G的V×V邻接矩阵G,在O(V)时间内判断是否存在一个数k,使得对所有的i有A[i][k]=1,对所有的j有A[k][j]=0,(i≠k,j≠k)

令i和j初值为1,若G[i][j]=0,说明i到j无边,j不可能是通用汇点,令j=j+1;若G[i][j]=1,说明i到j有边,i不可能是通用汇点,令i=i+1,循环直到i>|V|或者j>|V|;若i>|V|,则不存在通用汇点,若j>|V|,则检查顶点i是否满足要求。

伪代码:

判断是否存在通用汇点O(V)

HAS_UNIVERSL_SINK(G)

1i=j=1

2whilei≤Vandj≤V

3ifG[i][j]==1

4i=i+1

5elsej=j+1

6ifi>V

7returnfalse

8elsereturnCHECK(G,i)

CHECK(G,u)

1foreachvertexv∈

2ifG[u][v]=1

3returnfalse

4foreachvertexv∈

5ifG[v][u]==0&u!

=v

6returnfalse

7returntrue

检查点u是否是通用汇点

【宽度优先搜索】

计算无向图BFS后的d值和π值

简单,注意初始节点u的π值写NIL或者写-1

r

s

t

u

v

w

x

y

D值

4

3

1

0

5

2

1

1

π值

s

w

u

NIL

r

t

u

u

输入如果是邻接矩阵表示的,BFS的运行时间

O(V^2)

对于队列中的每一个节点,都要遍历所有的节点来判断是否有边。

举例说明一个有向图G中可能存在这样一个边集Eπ:

s到v的唯一简单路径也是一条最短路径,但是无论如何该边集Eπ都不能通过在图G上运行BFS获得。

V={1,2,3,4,5},E={(1,2),(2,3),(1,4),(4,5),(2,5),(3,4)},Eπ={(1,2),(2,3),(1,4),(4,5)},s=1

求一棵树T=(V,E)的直径,并分析算法的运行时间。

直径指的是树中所有最短路径的最大值。

两遍BFS就能解决.

设v任意一点,BFS(v),令u=v能到达的最远点。

再BFS(u),取w为u能达到的最远点,则u和w之间的最短路径就是直径。

时间复杂度是O(V+E)。

注意本题的证明。

反证法,设t1到t2是直径,u是v能达到的最远点,但是u不是t1或者t2中的一个,产生矛盾的结论。

【深度优先搜索】

给出DFS每个结点的发现时间和完成时间,并给出每条边的分类

q

r

s

t

u

v

w

x

y

z

dis/fin

1/16

17/20

2/7

8/15

18/19

3/6

4/5

9/12

13/14

10/11

qs

sv

vw

ws

qw

qt

tx

xz

zx

ty

yq

ry

uy

ru

树边

树边

树边

后向边

前向边

树边

树边

树边

后向边

树边

后向边

横向边

横向边

树边

用栈实现DFS,写出伪代码

DFS-VISIT(G,u)

1(u)

2while(!

3u=

4if==GRAY

5==BLACK

6time=time+1

7=time

8

9continue

10if==WHITE

11=GRAY

12time=time+1

13=time

14foreachv∈G:

Adj[u]

15if==WHITE

16v.π=u

17(v)

举出一个反例反驳:

有向图G包含u到v的路径,并且DFS时<,则v是u在DFS森林中的一个后代。

V={w,u,v}

E={(w,u),(u,w),(w,v)}

有一条从u到v的路径,u->w->v,且d[u]

w

u

v

dis

1

2

4

fin

6

3

5

举出一个反例反驳:

有向图G包含u到v的路径,则任意DFS都将导致≤。

例子同上

为什么节点u同时有入边和出边,u还是深度优先树中的唯一节点

V={w,u,v}

E={(u,w),(v,u)}

w

u

v

dis

1

3

5

fin

2

4

6

证明:

在无向图上使用深度优先搜索来获取图G的连通分量,并且深度优先搜索包含的树的棵数与G的连通分量相同。

也就是说,修改深度优先搜索让每个结点赋予一个介于1和k之间的整数值,k是G的连通分量数。

相同连通分量中的点有相同的。

将DFS_VISIT(G,u)改成DFS_VISIT(G,u,++k),然后在该方法开头添加一句=k。

给出一个算法判断一个有向图是单连通图

单连通:

图G至多包含一条从u到v的简单路径。

判断是否出现了前向边或者横向边即可。

即分别对每个顶点进行DFS,记录过程中是否访问到黑色的节点。

时间复杂度(V*(V+E))

伪代码:

SOLVE(G)

1foreachvertexu∈

2foreachvertexv∈

3=WHITE

4v.π=NIL

5time=0

6if(DFS(G,u))

7returnfalse

8returntrue

DFS(G,u)

1time=time+1

2=time

3=GRAY

4foreachv∈G:

Adj[u]

5if==WHITE

6v.π=u

7if(DFS(G,v))

8returntrue

9if==BLACK

10returntrue

=BLACK

12time=time+1

=time

14returnfalse

【拓扑排序】

Computethenumberofdistinctpathsfromstotinadirectedacyclicgraph

(要求线性时间复杂度)

为每个顶点声明数组dp[],dp[v]为s到v的路径数,初始化为0,dp[s]置为1。

进行拓扑排序,在拓扑排序的过程中,每到达一个节点u,其每个相连的节点v都将dp[v]加上dp[u]。

最后dp[t]就是s到t的路径数。

复杂度:

O(V+E)

给出一个算法来判断给定无向图G=(V,E)是否包含一个环路,复杂度O(V)

DFS,访问当前节点的邻接表时,如果存在某个节点已经被标记为访问状态,而且该节点不是当前节点的父亲,则终止DFS,存在环路。

拓扑排序的另一种做法:

重复寻找入度为0的结点,输出该结点,将该结点及其发出的边从图中删除。

请解释如何在O(V+E)的时间内实现这种思想。

如果图G包含环路,将会发生什么情况

利用队列Queue。

邻接链表存储这个图G。

开一个大小为|V|的degree数组用来存储入度,遍历邻接链表,将各个点的入度存入degree数组中(复杂度O(E))。

从degree中取出入度为0的结点存入队列Q中,通过遍历数组实现(O(V))。

删掉入度为0的点,删除的过程中将该点引出的边也删掉,顺便检测有没有其他点因此变成了入度为0,将这些点加入队列中。

因此到最后所有的点都进过一次队列,复杂度O(V),每条边也都被处理了一遍,复杂度O(E)。

所以O(V+E)。

环路的入度不会为0,边不会被删掉,点不会加入拓扑序中。

给出一个算法判断图G是否是半连通的。

证明算法的正确性并分析运行时间。

对于有向图,任意节点对,存在u到v的路径或者v到u的路径。

这个题和拓扑排序的另一种做法有关。

对半连通图进行拓扑排序过程中,入度为0的点不能同时有2个或者以上。

否则,这两个入度为0的点之间就没有路径了。

因此就用中的算法,要求保持队列中最多只有1个点,如果多于1个就不是半连通的了。

思考题22-3欧拉回路

强连通有向图G=(V,E)中的一个欧拉回路是指一条遍历图G中每条边恰好一次的环路。

这条环路可以多次访问同一个结点。

a.证明:

图G有一条欧拉回路当且仅当对于图中每个节点v,有in-degree(v)=out-degree(v)。

b.给出一个复杂度为O(E)的算法来找出图G的一条欧拉回路。

a.证明:

=>若强连通有向图G有欧拉回路,则可知对于出发点s,假设有x次从s出,则最后回到s必须恰好有x次,因此对于s,出度和入度必然相等。

假设对于某个非出发点v,出度与入度不相等;假设出度y大于入度x,则第x次从v离开后再也不能回到v,剩余·的y-x条边不能被访问到;假设出度y小于入度x,则第y+1次进入v后无法出去。

由此可知,对于非出发点v,入度与出度同样相等。

因此G有Euler回路则入度等于出度成立。

<=假设强连通图G的每个结点出度等于入度,则从出发点开始遍历,最终必然会回到出发点s。

因为如果最终没有回到出发点,会有一条s->v1->v2->…->vi的路径,其中vi不等于s,则遍历过程中进入vi的次数比从vi走出的次数多一次,这样就肯定有一条从vi出去的边没有被访问到。

所以不成立。

这样遍历一次后会形成一个子回路,再在这个子回路上某个不同于s点的s1点继续遍历,会形成一个以s1为起始点(也是终止点)的子回路,这两个回路没有公共边,而这两个子回路明显可以合并为一个回路,该回路为s->…->e->s1->f->…->s1->…->s,这样不断扩展就必然形成一个欧拉回路。

b.从任意点开始DFS并在DFS过程中保存回路上的边。

DFS的复杂度是O(E)的。

设e为连通图G的某条环路上权重最大的边,证明:

图G’=(V,E-{e})中存在一棵最小生成树,它也同时是G的最小生成树。

也就是说,G中存在一棵不包含边e的最小生成树。

证明:

反证。

假设G中所有最小生成树都包含e。

任取一个这样的最小生成树T,在T上去掉e,将T分为两棵子树T1和T2,T1上顶点集合为V1,T2上顶点集合为V2,则(V1,V2)是一个割。

e所在的圈至少穿越割(V1,V2)两次,C至少有2条边在(V1,V2)中,其中一条边是e。

令e’为除了e之外的另外一条边,则w(e’)≤w(e)。

将e’并到T1和T2上,将T1和T2连接成一棵新的生成树T‘。

由于T’是在T上去掉e、加入e’后形成的,因此w(T’)≤w(T)。

因此,T’也是G的一棵最小生成树,且T‘中不包含e,与假设矛盾。

23-4第三种最小生成树算法。

c.MayBE-MST-C(G,w)

1T=空集

2foreachedgee,takeninarbitraryorder

3T=T∪{e}

4ifThasacyclec

5lete’bemaximum-weightedgeonc

6T=T-{e’}

7returnT

证明:

算法实际上是在图G中删除一些圈上权值最重的边,最后得到一棵MST。

设删除的边依次是e1,e2,…em-n+1,剩余的图一次是G0,G1,..,Gm-n+1,其中G=G0,Gm-n+1=T,m=|E|,n=|V|。

证明Gi+1的MST同时也是Gi的MST即可。

前面已经证明存在Gi+1的MSTT’同时也是Gi的MST,而Gi+1的所有MST的大小与T’一样,所以它们都与Gi的MST大小一样,所以它们都是Gi的MST。

从而Gm-n+1必然是Gm-n,…,G0的MST。

23-1次优最小生成树

每次从最小生成树里换掉一条边,用不在最小生成树中的一边代替。

23-3瓶颈生成树

最小生成树是瓶颈生成树。

假定G为一个带权重的有向图,并且图中存在一个权重为负值的环路。

给出一个有效算法列出所有属于该环路上的结点。

证明正确性。

对G进行改造,增加一个新的顶点s,以及s到G中所有顶点的边。

边上的权重均为0.记为G’=(V’,E’)。

将E中的边任意定一个顺序。

对E中每一条边e,将e从G‘上去掉,调用Bellmanford算法测试当前图上是否有负圈。

若有,将e永久删除。

否则,表明e在剩下的唯一一个负圈中,将e放回G’。

测试完E中所有的边之后,最后留在G’中的就是负圈。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1