我一开始接触图的时候,对图的遍历有一个恐惧的一点在于:如何判断我是否已经遍历过了,还有出现重复遍历的话咋办?
除此之外我们在遍历图之前,由于图结构的本身就很复杂,我们需要解决一些关键性的问题以及解决方法:
-
问题:在图中,不像树有一个根节点,所以是没有一个确定的开始顶点,这就会导致任意一个顶点都可作为遍历的起始顶点,那么,我们改如何选取遍历的起始顶点?
方法:既然图中没有确定的开始顶点,那么可从图中任一顶点出发,不妨将顶点进行编号,先从编号小的顶点开始。
-
问题:从某个顶点出发可能到达不了所有其他顶点,这个情况是的,例如非连通图,从一个顶点出发,只能访问它所在连通分量上的所有顶点,那么,如何才能遍历图的所有顶点?
方法:要遍历图中所有顶点,只需多次重复从某一顶点出发进行图的遍历。如果是非连通图,我们可以分别遍历他的连通分量。
-
问题:由于图中可能存在回路,某些顶点可能会被重复访问,这个问题一开始困扰我很久。那么,如何避免遍历不会因回路而陷入死循环?
方法:为了在遍历过程中区分顶点是否已被访问,设置一个访问标志数组visitedn,其初值为未被访问标志0,如果某顶点i已被访问,则将该顶点的访问标志visited[i]置为1。
-
问题:在图中,一个顶点可以和其他多个顶点相邻接,当这样的顶点访问过后,如何选取下一个要访问的顶点?
方法:这就是遍历次序的问题。图的遍历通常有深度优先遍历和广度优先遍历两种方式,这两种遍历次序对无向图和有向图都适用。
图的遍历一般分为深度优先遍历和广度优先遍历:
深度优先遍历(depth-first traverse)类似树的前序遍历,从图中某顶点v出发进行深度优先遍历的基本思想是:
1.访问顶点v:
2.从v的未被访问的邻接点中选取一个顶点w,然后从w出发进行深度优先遍历:
3.重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。
广度优先遍历(breadth-first traverse)类似树的层序遍历),从图中某顶点v出发进行广度优先遍历的基本思想是:
1.访问顶点v:
2.依次访问v的各个未被访问的邻接点v1,v2,……,vk;
3.v1,v2,……,vk,出发依次访问它们未被访问的邻接点,直至图中所有与顶点v有路径相通的顶点都被访问到。
了解这些基本知识,我们就很好掌握图的遍历实现了。希望有帮助到各位。