首页
|
新闻
|
新品
|
文库
|
方案
|
视频
|
下载
|
商城
|
开发板
|
数据中心
|
座谈新版
|
培训
|
工具
|
博客
|
论坛
|
百科
|
GEC
|
活动
|
主题月
|
电子展
注册
登录
论坛
博客
搜索
帮助
导航
默认风格
uchome
discuz6
GreenM
»
DSP技术
» 图论算法 有图有代码 万字总结 向前辈致敬(7)
返回列表
回复
发帖
发新话题
发布投票
发布悬赏
发布辩论
发布活动
发布视频
发布商品
图论算法 有图有代码 万字总结 向前辈致敬(7)
发短消息
加为好友
yuyang911220
当前离线
UID
1029342
帖子
9914
精华
0
积分
4959
阅读权限
90
在线时间
286 小时
注册时间
2014-5-22
最后登录
2017-7-24
论坛元老
UID
1029342
性别
男
1
#
打印
字体大小:
t
T
yuyang911220
发表于 2016-8-20 19:51
|
只看该作者
图论算法 有图有代码 万字总结 向前辈致敬(7)
search
,
false
,
推广
深度优先搜索
深度优先搜索(depth-first search)是对前序遍历的推广,对每一个顶点,字段visited被初始化成false,通过哪些尚未被访问的结点递归调用该过程,我们保证不会陷入无限循环。如果图是无向且连通的,或是有向但非强连通的,这种方法可能会访问不到某些结点。此时我们搜索一个未被标记的结点,然后应用深度优先遍历,并继续这个过程直到不存在未标记的结点为止。因为该方法保证每一条边只被访问一次,所以只要使用邻接表,执行遍历的总时间就是O(|E|+|V|)。
深度优先搜索的算法实现:
#define FALSE 0 #define TRUE 1 short int visited[MAX_VERTICES] void dfs(int v) { node_pointer w; visited[v]=TRUE; printf("%5d",v); for(w=graph[v];w;w=w->link); if(!visited[w->vertex]) dfs(w->vertex); }
1
2
3
4
5
6
7
8
9
10
11
12
13
和上文中的广搜一样,我们也来对dfs进行分析。
如果采用邻接表来存储,就可以沿着顶点的链表来确定其所有邻接顶点。因此在邻接表中的每一个顶点都至多扫描一次,所以完成搜索时间复杂性为O(e)。
如果采用邻接矩阵来存储,访问顶点的所有邻接顶点的时间为O(n),而整个过程至多访问n个顶点,因此完成搜索时间复杂性为O(n2)。
无向图
如下左图中是一个无向图,我们以此为例,假设从A开始,标记A为known并递归地调用dfs(B)。dfs(B)标记B为known并递归调用dfs(C)。dfs(C)标记C为known并递归调用dsf(D)。而后D的邻接结点只有C,但C已经是knwon的,这里便无法再继续递归下去,因此返回到dfs(C)。dfs(C)看到已经标记为known的B邻接点和D邻接点,因此调用dfs(E)。dfs(E)标记E为known,同样的它只能返回到dfs(C),再返回到dfs(B),最后返回到dfs(A)。实际上这里接触每条边2次,一次是作为边(v,w),另一次是作为边(w,v)。
如下右图展示了深度优先搜索树(depth-first spanning tree)的步骤。虚线表示向后边(back edge),表示这条“边”并不是树的一部分。
树将模拟我们执行的遍历,使用树的边对该树的前序编号(preorder numbering)表示顶点被标记的顺序;如果图不是连通的,那么处理所有的结点(以及边)自然需要多次反复调用dfs,每次都生成一棵树,整个集合就是深度优先生成森林(depth-first spanning forest)。
双连通性
前面我们已经介绍过了双连通图,如果删除一个无向图的仁一顶点后,剩下的图仍然连通,那么这样的无向连通图就称为是双连通的(biconnected)。
如果图不是双联通的,那么将其删除后不再连通的那些顶点叫做割点(articulation point)。
深度优先搜索提供了一种找出连通图中所有割点的线性时间算法。从图中任一顶点开始,执行深度优先搜索并在顶点被访问时给它们编号。对于每一个顶点v,我们称其前序编号为Num(V)。然后,对于深度优先搜索生成树中的每一个顶点v,计算编号最低的顶点,我们称之为Low(V),该点可从v开始通过树的零条或多条边,且可能还有一条后向边而以该序达到。
有向图
如前所述,如果图不是强连通的,那么从某个结点开始的深度优先搜索可能访问不了所有的结点,这种情况下我们从某个未做标记的结点处开始,反复执行深度优先搜索,直到所有的结点都被访问到为止。
对此我们从顶点B开始深度优先搜索,依次访问B、C、A、D、E、F。而后从某个未被标记的顶点重新开始,比如H,然后访问J和I。最后从G开始,也从此结束。
深度优先生成森林中的虚线是一些(v,w)边,其中的w在考察时已经做了标记。在无向图中,它们总是一些向后边,但是可以看到,存在三种类型的边并不通向新的顶点。这里有一些向后边(back edge),如(A,B);还有一些向前边(forward edge),如(C,D);最后还有一些交叉边(cross edge),如(F,C),它们把不直接相关的两个树结点连接起来。深度优先搜索森林一般通过把一些子结点和一些新的树丛左到右添加到森林中形成。
深度优先搜索还可以用来检测一个有向图是否是无环图,因为一个有向图是无环图当且仅当它没有向后边。上面的例子明显不是无环图,因为它有向后边。而拓扑排序也可以用来检测一个图是否是无环图,进行拓扑排序的另一种方法是通过深度优先搜索生成森林的后序遍历给顶点指定拓扑编号N,N−1,……,1。只要图是无环的,这种排序就是一致的。
收藏
分享
评分
继承事业,薪火相传
回复
引用
订阅
TOP
发短消息
加为好友
yuchengze
当前离线
UID
1062083
帖子
5837
精华
0
积分
2921
阅读权限
70
在线时间
222 小时
注册时间
2016-6-30
最后登录
2018-9-9
金牌会员
UID
1062083
性别
男
2
#
yuchengze
发表于 2016-8-21 12:14
|
只看该作者
很好的算法分析,感谢楼主的分享,完美解决了我的问题
回复
引用
TOP
返回列表
电商论坛
Pine A64
资料下载
方案分享
FAQ
行业应用
消费电子
便携式设备
医疗电子
汽车电子
工业控制
热门技术
智能可穿戴
3D打印
智能家居
综合设计
示波器技术
存储器
电子制造
计算机和外设
软件开发
分立器件
传感器技术
无源元件
资料共享
PCB综合技术
综合技术交流
EDA
MCU 单片机技术
ST MCU
Freescale MCU
NXP MCU
新唐 MCU
MIPS
X86
ARM
PowerPC
DSP技术
嵌入式技术
FPGA/CPLD可编程逻辑
模拟电路
数字电路
富士通半导体FRAM 铁电存储器“免费样片”使用心得
电源与功率管理
LED技术
测试测量
通信技术
3G
无线技术
微波在线
综合交流区
职场驿站
活动专区
在线座谈交流区
紧缺人才培训课程交流区
意见和建议