本文目录
深度优先(DFS-Depth First Search)
基本思想
仿树的先序遍历过程
简单归纳
- 访问起始点v
- 若v的第1个邻接点没访问过,深度遍历此邻接点
- 若当前邻接点已访问过,再找v的第2个邻接点重新遍历。
举个例子
深度优先遍历结果:2->1->3->5->4->6
详细归纳
- 在访问图中某一起始顶点 v 后,由 v 出发,访问它的任一邻接顶点 w1;
- 再从 w1 出发,访问与 w1邻接但还未被访问过的顶点 w2;
- 然后再从 w2 出发,进行类似的访问,…
- 如此进行下去,直至到达所有的邻接顶点都被访问过的顶点 u 为止。
- 接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。
如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;
如果没有,就再退回一步进行搜索。重复上述过程,直到连通图中所有顶点都被访问过为止。
代码
仍可用递归算法
void DFS(ALGraph G, int v)
{ //图G为邻接表类型
cout<<v; visited\[v\] = true; //访问第v个顶点
p= G.vertices\[v\].firstarc; //p指向v的边链表的第一个边结点
while(p!=NULL)
{ //边结点非空
w=p->adjvex; //表示w是v的邻接点
if(!visited\[w\]) DFS(G, w); //如果w未访问,则递归调用DFS
p=p->nextarc; //p指向下一个边结点
}
}
效率分析
时间复杂度
邻接矩阵O(n²) 邻接表O(n+e)
结论
稠密图适于在邻接矩阵上进行深度遍历,
稀疏图适于在邻接表上进行深度遍历。
广度优先(BFS-Breadth First Search)
基本思想
仿树的层次遍历过程
简单归纳
- 在访问了起始点v之后,依次访问v的邻接点
- 然后再依次访问这些顶点中未被访问过的邻接点
- 直到所有顶点都被访问过为止
广度优先搜索是一种分层的搜索过程,每向前走一步,可能访问一批顶点,不像深度优先搜索那样有回退的情况。
因此,广度优先搜索不是一个递归的过程,其算法也不是递归的
辅助队列
从图中某个顶点v出发,访问v,并置visited[v]的值为ture,然后将v进队
只要队列不空,则重复下述处理。
- 队头顶点u出队
- 依次检查u的所有邻接点w,如果visited[w]的值为false,则访问w,并置visited[w]的值为ture,然后将w进队。
代码
void BFS (Graph G, int v)
{
//按广度优先非递归遍历连通图G
cout<<v; visited\[v\] = true; //访问第v个顶点
InitQueue(Q); //辅助队列Q初始化,置空
EnQueue(Q, v); //v进队
while(!QueueEmpty(Q)) //队列非空
{
DeQueue(Q, u); //队头元素出队并置为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进队
}//if
}//while
}//BFS
效率分析
时间复杂度
邻接矩阵O(n2) 邻接表O(n+e)
只与存储结构有关,与搜索路径无关
空间复杂度
都是O(n)(借用了堆栈或队列)