遍历时,每个顶点仅访问一次
避免重复访问:设置辅助数组vistied[n],初始状态置为0,访问后修改为1
实质:找到每个点的邻接点
深度优先搜索DFS
方法: ①从起始顶点开始访问任意一个邻接顶点,然后再继续访问该点的邻接结点直到最后的没有邻接结点未被访问(一条路走到头)
②当走到头时回退到上一结点,查找是否还有未访问结点,有的话执行步骤①,没有的话继续回退,直到回退到起始结点
类似于树的先序遍历
实现(邻接矩阵)
DFS结果:2->1->3->5->4->6(循环遍历对应行第一个为访问的结点)
void DFS(AMGraph G,int v){
cout<<v; visit[v]=true; //访问结点V
for(w=0;w<G.vexnum;w++){
if((G.arc[v][w]!=0) && (!visited[w]))
DFS(G,w); //w是v的邻接点,如w未访问,递归调用DFS
}
}
使用邻接矩阵表示:时间复杂度为O(n^2)
使用邻接表表示:时间复杂度为O(n+e)
结论: 稠密图适于在邻接矩阵上使用DFS
稀疏图适于在邻接表上进行DFS
如果是非连通图,则对各个图依次使用DFS
广度优先搜索BFS
方法: ①从起始结点出发,访问它全部的邻接点
②按照之前的顺序访问所有邻接点的邻接点,直到没有未被访问的顶点为止
BFS访问路径V1->V2->V3->V4->V5->V6->V7->V8
实现
void BFS(Graph G,int v){
cout<<v;visited[v]=true; //访问v结点
InitQueue(Q); //初始化辅助队列Q
EnQueue(Q,v); //v进队
while(!QueueEmpty(Q)){ //非空队列
DeQueue(Q,u); //队头元素出队
for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))
if(!visited[w]){ //w为u的未访问邻接点
cout<<w; visited[w]=true; EnQueue(Q,w); //w进队
}
}
}
使用邻接矩阵表示:时间复杂度为O(n^2)
使用邻接表表示:时间复杂度为O(n+e)
DFS和BFS空间复杂度相同,均为O(n)
时间复杂度仅与存储结构有关,与搜索路径无关