所谓深度优先:从图中某个初始顶点v出发,首先访问初始顶点v,然后选择一个与顶点v相邻且没被访问过的顶点w为初始顶点,再从w出发进行深度优先搜索,直到图中与当前顶点v邻接的所有顶点都被访问过为止。显然,这个遍历过程是个递归过程。
对于一个无向图的深度优先访问,需要注意,每条边被访问了两次,对边的第一次访问v-w,存在两种情况:第一种直接进行w的递归调用,因为w没有访问过;第二种情况是w已经被访问过,忽略对w的调用。需要注意的是第二种情况下,v-w是形成了一个回边,也就是说,实际上与原来的递归调用路径形成了一个环。这点很有用。对边的第二次访问,都忽略递归调用,也存在两种情况,第一种是访问的节点是其父节点;第二种是访问的节点的递归调用已经完成,而本节点还在进行递归调用。
总结一句话:边分为树边(进行递归调用的边)和回边(不进行递归调用的边,形成环的边)。根据访问次数,可以分为四种链接:树链接,父链接(树边的两次访问);回链接,下链接(回边的对应的两次访问)。
怎么来识别这些边呢?因为树的递归调用,在调用前,我们使用一个数组ord来记录调用的秩序,类似树的前序遍历,再使用一个数组st来记录每条递归调用边的父节点。通过这两个数组就可以识别上面的边的两次访问情况。
对于每次边的调用v-w
1) ord[w]=-1,那么v-w是树链接,进行递归调用。
2) ord[w]<ord[v],说明w已经原来进行访问过,如果st[v]=w,则v-w是父链接。否则是回链接。(既然是回链接,则指向的节点肯定已经先访问过)。
3) ord[w]>ord[v],则v-w是下链接,w节点的递归调用已经完成,v节点还在进行。
DFS的应用:
1) 环的检测,这个是很容易。根据上面的分析,判断是否是回链接就可以实现。
2) 可分离图:就是说图中存在桥(一个桥是一条特定的边,可以把一个连通图分解为不相交的两个子图)的图。根据DFS的边的特性的分析,回边是不可能是桥。桥v-w有个特性,对于节点w,没有一条回边将其子孙与其某个祖先相连。可以使用一个数组来记录节点w为根的的子树中任何回边所引用的最小前序编号(ord值)。
public void dfs (int v) {
ord[v] = cnt++;
low[v] = ord[v];
for (int w : G.adj(v)) {
if (ord[w] == -1) {
st[w] = v;
dfs2(w);
/**
* 访问完一个节点后,看这个节点子树中回边指向的最小祖先节点
*/
if (low[v] > low[w])
low[v] = low[w];
/**
* 一个节点回边指向的最先祖先节点是其本身,那么这条边是桥
*/
if (low[w] == ord[w]) {
System.out.println(v + "-------------------->" + w
+ " is bridge!");
}
} else
if (st[v] != w && ord[w] < ord[v]) {
/**
* 节点v的子节点的回边的节点小于本节点记录值
*/
if (low[v] > ord[w])
low[v] = ord[w];
}
}
}
3)图的连通性。
分享到:
相关推荐
无向图的深度优先生成树(DFS,Depth-First Search)和广度优先生成树(BFS,Breadth-First Search)是图论中的两种基本遍历算法,广泛应用于计算机科学,特别是在数据结构和算法设计中。这两种方法用于访问图的所有...
无向图建立、深度优先遍历和广度优先遍历实现算法 本文将详细介绍无向图的建立、深度优先遍历和广度优先遍历的实现算法。这些算法是数据结构中非常重要的内容,掌握它们对后续学习和应用非常重要。 一、无向图的...
以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。 注: 1.代码共182行。 2.代码经过多次编译运行,无错误。
在这个程序设计任务中,我们需要实现的是连通无向图的深度优先遍历(DFS)和广度优先遍历(BFS),这两种遍历方法是图算法的基础。无向图指的是图中的边没有方向,即任意两个节点之间可以双向连接。 1. **邻接表和...
通过键盘输入图的顶点,以及每一条边的两个顶点,从而建立无向图。实现无向图的深度优先遍历算法。要求以用户给定的结点为起始点,显示深度优先遍历次序。
无向图的深度优先搜索(DFS, Depth-First Search)和宽度优先搜索(BFS, Breadth-First Search)是图论中两种重要的遍历算法,它们被广泛应用于解决各种问题,如查找路径、判断连通性、求最短路径等。在C++中实现这...
总结来说,深度优先搜索在有向无环图中寻找最优路径是一种有效的方法,它通过遍历所有可能的路径并实时更新最优解,最终找到具有最小权值的路径。在实现过程中,需要注意优化存储结构和搜索过程,以提高效率和准确性...
在有向图中,每个节点(或顶点)可以连接到其他节点,形成一种单向的链接关系。深度优先搜索在寻找两个特定顶点之间是否存在路径时非常有用。在描述的问题中,我们需要找出是否有从顶点Vi到Vj的路径,且i≠j。这通常...
在无向图中,DFS会从一个起点开始,访问该节点,然后选择一个未被访问的邻接节点进行访问,直到遍历完所有可达节点。若无法继续沿着当前路径前进,就回溯到上一节点,继续寻找未访问的邻接节点。DFS的特点是可能会先...
通过本文的介绍,读者应该能够理解无向图的深度优先遍历算法,并能根据所提供的示例代码实现自己的无向图深度优先遍历程序。这种遍历方式对于解决图理论中的许多问题非常有用,例如最短路径问题、拓扑排序等。
给定的代码实现了一个基于邻接表的无向图的深度优先遍历算法。下面,我们将分步骤解析这段代码的关键部分。 ##### 创建邻接表表示的无向图 ```c int Create_Adj_List_undirected_graph(AdjList*&G){ // ...代码...
在无向图中,从一个节点出发的边和指向该节点的边是对称的,因此DFS会同时考虑两者。而在有向图中,DFS只考虑从当前节点出发的边,忽略指向当前节点的边,因为有向边具有方向性。 DFS和其他搜索算法相比,有其独特...
数据结构课程中的深度优先搜索算法、广度优先搜索算法的C语言程序,在Turbo C 2.0上调试通过。
深度优先搜索(Depth-First Search, DFS)是一种用于遍历或搜索树或图的算法,它的基本思想是从起点开始,尽可能深地探索图的分支,直到达到叶子节点或回溯到一个未被访问过的节点。在VC++6.0环境下,我们可以编写...
本话题将深入探讨如何使用邻接矩阵来实现无向图的广度优先搜索(BFS)和深度优先搜索(DFS)的文件操作。 首先,邻接矩阵是一个二维数组,其中的元素代表图中节点之间的连接。如果节点i与节点j之间有一条边,那么在...
**标签"图论"**意味着此算法应用于图结构的分析和处理,包括但不限于有向图、无向图、加权图和无权图等。 在提供的压缩包文件中,"DFS深度优先遍历"可能是包含实现DFS算法的源代码文件,通过运行这些代码,我们可以...
在无向图中,DFS可以生成一棵深度优先搜索树(DFS Tree),这棵树的特点是从起点开始,沿着每条边向下探索,直到没有未访问的邻接顶点为止。如果从一个顶点出发,DFS不能到达所有的顶点,那么结果将是一片DFS森林,...
寻路算法中最基础的python深度优先算法。该资源包含了深度优先搜索的两种实现方式。 第一种利用递归的深度优先搜索算法。这个例子中,我们假设数据结构是一个无向图,用邻接表来表示。 第二种使用栈的深度优先搜索...
"无向图深度遍历邻接矩阵报告.doc" 本报告旨在掌握图的结构特征、邻接矩阵和邻接表存储结构的特点和实现,以及在邻接矩阵或邻接表存储结构下图的深度优先和广度优先遍历算法思想及其程序实现。 一、图的结构特征 ...
无向图的广度优先生成树(BFS Tree)是一种在无向图中寻找特定根节点的树形结构,该树的构造方式是通过广度优先搜索(Breadth-First Search, BFS)进行的。在图论和计算机科学中,这种遍历方法常用于寻找最短路径、...