图的深度优先遍历,基本思想是访问顶点,然后访问v0邻接到的未被访问的点顶点v1,在从v1出发递归地按照深度优先的方式遍历。当遇到一个所有邻接于它的顶点都被访问了的顶点u时,则回到已访问顶点的序列中最后一个拥有未被访问的相邻顶点的顶点w,从w出发继续访问。最终当任何已被访问的顶点都没有未被访问的相邻顶点时,遍历结束。也就是说深度优先遍历是沿着图的某一条分支遍历,直到末端,然后回溯,沿着另一条分支进行同样的遍历,直到所有的分支都被遍历过为止。
基于链式前向星的代码:
bool s[maxn]={0};
void dfs(int x)
{
s[x]=true;
printf("%d\n",x);
int i;
for(i=head[x];x!=-1;i=edge[i].next)
{
if(s[edge[i].to])
dfs(edge[i].to);
}
}
图的宽度优先遍历与深度优先遍历不同之处在于:宽度优先遍历访问顶点v0然后访问v0邻接的未被访问的所有顶点,v1,v2,····vn,在依次访问v1,v2,···vn连接到的未被访问的所有顶点,如此下去,直到所有点都被访问。
代码:
bool s[maxn];
void bfs(int x)
{
int queue[maxn];
int iq=0;
queue[iq++]=x;
int i=k;
for(int i=0;i<iq;iq++)
{
//每次从队头取节点,一定是下一个待扩展节点;
printf("%d\n",queue[i]);
//遍历与当前节点相连接的节点,如果没有未被访问过,入队
for(k=head[queue[i]];k!=-1;k=edge[k].next)
{
if(!s[edge[k].to)
{
queue[iq++]=edge[k].to;
}
}
}
}
宽度优先遍历和深度优先遍历的时间复杂度相同,O(n)。