深度优先搜索:
深度优先搜索是对先序遍历的一般化。我们从某个节点开始,先处理,并将标记为已知,然后任意选择的一个邻接顶点,对其进行深度优先搜索,这样就递归的遍历了图的所有顶点。当图中有圈时,需要注意在选择邻接顶点时,要选择未知的邻接顶点(通过只对尚未访问的顶点进行深度优先搜索,能够避免进入死循环)。深度优先搜索的时间复杂度是。
无向图的连通性:
当且仅当从任意节点开始的深度优先搜索访问到图中的每一个顶点,无向图是连通的。
以下图为例,从A点开始对无向图进行深度优先搜索:
首先,标记A为已知,接着选择对B进行深度优先搜索;将B标记为已知,并对C进行深度优先搜索;将C标记为已知并对E进行深度优先搜索;将E标记为已知后,发现E的邻接顶点都已经被访问过,于是开始退出递归;在退回到C这一层时,对D进行深度优先搜索之后,退出所有递归程序。得到上图的深度优先生成树(如下所示)。
从A开始,当我们在处理边时发现是未知的,我们就将这条边加入到树中,如果是已知的,那么边就是一条背向边,在图中用虚线表示,但它不属于生成树。
如果图是连通的,就会生成一棵深度优先搜索生成树;如果图不连通,就需要调用多次深度优先搜索,每次都生成一棵树,最终会形成深度优先生成森林。
有向图的遍历:
深度优先搜索可以用来遍历有向图,如果有向图不是强连通的,就需要调用多次深度优先搜索,生成深度优先生成森林。
对于上图,从B开始进行深度优先搜索,将B标记为已知,并对C进行深度优先搜索,然后依次遍历A,D,E,F节点。可以看到,此时图中的节点并没有被遍历完,所以还需要从H开始进行依次深度优先搜索,依次遍历H,J,I;最后还需要对G进行一次深度优先搜索。总共生成了三棵深度优先生成树。
在深度优先生成森林中有三种类型的虚线边:指向后裔的是前向边;指向其上一层节点的边是背向边;指向同一层节点的边是交叉边(以两个节点的父节点为基准来判断层数),交叉边一般从右指向左,因为深度优先搜索一般先遍历左子树,如果交叉边从左指向右,那么在深度优先搜索中,它就会是一条前向边,因为右侧的节点肯定还没有被访问。同无向图一样,有向图的深度优先生成树中的虚线也不属于树。
深度优先搜索还可以用来检测有向图中是否无圈,法则如下:一个有向图无圈当且仅当其深度优先生成树中没有背向边。