深度优先搜索
一、深度优先搜索DFS(Depth First Search)
(一)深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广。
(二)假设初始状态是图中所有顶点未曾访问,则深度优先搜索可从图中某个顶点V出发,访问此顶点,然后依次从V的未被访问的邻接点出发深度优先遍历图,直到图中所有和V有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为起始点,重复上述过程,直至图中所有顶点都被访问到为止。
二、深度优先搜索的示例
图7-9
三、深度优先搜索小结
◆ DFS 在访问图中某一起始顶点v后,由v出发,访问它的任一邻接顶点w1;再从w1出发,访问与w1邻接但还没有访问过的顶点w2;然后再从w2出发,进行类似的访问,… 如此进行下去,直至到达所有的邻接顶点都被访问过的顶点u为止。
◆ 接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就再退回一步进行搜索。重复上述过程,直到连通图中所有顶点都被访问过为止。
四、举例
图7-10
五、深度优先搜索算法
void DFSTraverse(Graph G,Status (*visit)(int v)){
//对图G作深度优先遍历
visitFunc=visit;
for (v=0;v<G.vexnum;++v) visited[v]=false;
for (v=0;v<G.vexnum;++v)
if(!visited[v]) dfs(G,v); //对尚未访问的顶点调用dfs
}
void dfs(Graph G,int v){
//从第v个顶点出发递归地深度优先搜索图G。
visited[v]=true;visitfunc(v);
for(w=firstadjvex(G,v);w;w=nextadjvex(G,v,w))
if(!visited[w]) dfs(G,w) //对v的尚未访问的邻接顶点w递归调用dfs
}
六、算法小结:
◆ 图中有n个顶点,e条边。如果用邻接表表示图,沿Firstout指针域链可以找到某个顶点v的所有邻接顶点w。由于总共有2e个表结点,所以扫描边的时间为O(e)。而且对所有顶点递归访问1次,所以遍历图的时间复杂性为O(n+e)。
◆ 如果用邻接矩阵表示图,则查找每一个顶点的所有的边,所需时间为O(n),则遍历图中所有的顶点所需的时间为O(n2)。