图的遍历:
图的两种遍历方法:DFS和BFS
这里只讲了常用的递归法,还有一种迭代法(这个是在代码随想录中看到才知道有这种方法,应该,应该递归法就够用了)
DFS(深度优先遍历):
dfs算法简单的思路就是找到一个起始点,然后找该点的第一个没有被访问到的儿子,访问该点,然后找该点第一个没有被访问到的儿子……。可以看出是一个递归算法。深度优先遍历的简单介绍就是按着一条线一直往下走就好。(看一下树的深度优先遍历更容易理解,当然学到了图肯定理解什么意思了)
以上图为例,以0以起始点,遍历0,0的第一个儿子是1,遍历1,1的儿子是3,遍历3,然后遍历4,遍历2,此时发现2的儿子0已经被遍历了且没有其他儿子,就退回到4(这里退回的意思是,因为在DFS算法中,for循环所有点的,所哟如果i = 2那条路结束就i= 3,3不是4儿子且已经被遍历就i = 4 ,4不是他儿子且已经被遍历就i = 5 ,4是4儿子且未被遍历,所以就进行这一条路接着遍历),4的下一个儿子是5,遍历5,5的下一个儿子是6,遍历6.
void DFS(int v, void (*PreVisit)(int v), void (*PostVisit)(int v), void (*Visiting)(int v)) // Depth first search
{
PreVisit(v) ;
Visiting(v) ;
G->setMark(v,VISITED) ;
for(int i = G->first(v) ; i < G->n() ; i = G->next(v,i))
{
if(G->getMark(i) == UNVISITED)
{
DFS(i,*PreVisit,*PostVisit,*Visiting) ;
}
}
PostVisit(v) ;
}
BFS:
bfs算法简单的思路就是找到一个起始点,然后找该点的所有儿子,然后依次访问他儿子的所有儿子……可以看出是一个递归算法。可能直接这样说有点难理解,看完下面的示例就懂什么意思了,(有点像树的层序遍历),理解不了就,就,建议看哔站视频
友情提示:这里用到了queue(队列)
以上图为例,以0以起始点,将0放到队列中。遍历0,0的儿子有1和2,将1和2放到队列中。此时队列中的顺序是1、2。依次遍历1和2,先遍历1,1的儿子有3和5,将3和5放到队列中。遍历2,2的儿子有4和5,但5已经被遍历,所以只将4放到队列中。(这里1,和2是一层,遍历完了这一层)。此时队列中的顺序是3、5、4。先遍历3,3的儿子5已经放到了队列。然后遍历5,5的儿子4已经放到了队列。然后遍历4,4没有儿子。
void BFS(int start, void (*PreVisit)(int v), void (*PostVisit)(int v), void (*Visiting)(int v))
{
int v , i ;
queue<int> Q ;
Q.push(start) ;
PreVisit(start) ;
G->setMark(start,VISITED) ;
while(!Q.empty())
{
v = Q.front() ;
Q.pop() ;
Visiting(v) ;
for(i = G->first(v) ; i < G->n() ; i = G->next(v,i))
{
if(G->getMark(i) == UNVISITED)
{
G->setMark(i,VISITED) ;
Q.push(i) ;
PreVisit(i) ;
}
}
PostVisit(v) ;
}
}