图的遍历方法主要有两种:(1)深度优先遍历,类似于树的先序遍历;(2)广度优先遍历,类似于树的层序遍历。
遍历设计三思:(1)图没有首尾之分,所以算法中必须指定访问的第一个结点;(2)图的遍历过程中可能会构成一个回路,造成死循环,所以要考虑到所有的死循环问题;(3)一个结点可能和多个结点都是邻接关系,所以要使一个结点的所有邻接结点按照某种次序被访问。
图又分连通图和非连通图,连通图中,从初始结点出发,一定存在路径和图中的所有其他结点相连。而非连通图,从某一结点开始并不能访问图中的所有结点。所以,我们要分开设计。
连通图的深度优先遍历:
从初始结点出发,遵守深度优先规则,即在图的所有邻接结点中,每次都在访问完当前结点后首先访问当前结点的第一个邻接结点,该算法是一个递归算法,设计如下。
(1)访问结点v并标记结点v为已访问;
(2)查找结点v的第一个邻接结点w;
(3)若结点w存在,则继续执行,否则算法结束;
(4)若结点w尚未被访问,则以结点w开始进行深度优先遍历(递归)访问结点w;
(5)若结点w已被访问过,则查找结点v的w邻接结点的下一个邻接结点w,转步骤3。
注:该递归算法属于回溯算法。
连通图的广度优先遍历:
类比于树的分层遍历,广度优先遍历需要一个队列以保存访问过的结点顺序,以便按访问过的结点顺序来访问这些结点的邻接结点,设计如下。
(1)访问结点v并标记结点v为已访问;
(2)结点v入队列;
(3)当队列非空,则继续执行,否则算法结束;
(4)出队列取得队头结点u;
(5)查找结点u的第一个邻接结点w;
(6)若结点u的邻接结点w不存在,转步骤3,否则循环执行以下:
1、若结点w未被访问,则访问结点w,并标记w为已访问;
2、结点w入队列;