借着毕设又复习了一下数据结构的知识和课堂讲义,来源:老师的讲义
图的遍历
在图的遍历算法设计中,需要考虑三个问题:
(1)访问的第一个顶点需要被指定;
(2)避免遍历路径可能出现的死循环问题。
图中可能存在回路,且图的任一顶点都可能与其它顶点相通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过的顶点。为了避免这种重复访问,可设置一个标志顶点是否被访问过的辅助数组 visited [ ]。
辅助数组visited[ ]的初始状态为 0, 在图的遍历过程中, 一旦某一个顶点 i 被访问, 就立即让visited[i]为 1, 防止它被多次访问;
(3)要使一个顶点的所有邻接顶点按照某种次序被访问。
图的遍历的分为深度优先搜索 DFS (Depth First Search)与广度优先搜索 BFS (Breadth FirstSearch)两类。
DFS深度优先搜索
DFS 在访问图中某一起始顶点 v 后, 由 v 出发, 访问它的任一邻接顶点 w1; 再从 w1 出发, 访问与 w1邻接但还没有访问过的顶点 w2; 然后再从 w2 出发, 进行类似的访问, … 如此向纵深方向进行下去, 直至到达所有的邻接顶点都被访问过的顶点 u 为止。接着, 退回一步, 退到前一次刚访问过的顶点, 看是否还有其它没有被访问的邻接顶点。如果有, 则访问此顶点, 之后再从此顶点出发, 进行与前述类似的访问; 如果没有, 就再退回一步进行搜索。重复上述过程, 直到连通图中所有顶点都被访问过为止。最后可以得到一颗深度优先生成树,但不唯一。
连通图的深度优先遍历递归(回溯)算法为:
(1)访问顶点v并标记顶点v为已访问;
(2)查找顶点v的第一个邻接顶点w;
(3)若顶点v的邻接顶点w存在,则继续执行,否则算法结束;
(4)若顶点w尚未被访问则深度优先搜索递归访问顶点w;
(5)查找顶点v的w邻接顶点的下一个邻接顶点w,转到步骤(3)。
邻接矩阵存储结构图类的深度优先遍历成员函数如下(递归):
java实现
邻接矩阵存储结构图类的深度优先遍历成员函数如下(递归):
void depthFirstSearch(int v, boolean[] visited, Visit vs) throws Exception{
//连通图以v为初始结点序号、访问操作为vs的深度优先遍历
//数组visited标记了相应结点是否已访问过,0表示未访问,1表示已访问
vs.print(getValue(v)); //访问该结点
visited[v] = true; //置已访问标记
int w = getFirstNeighbor(v); //取第一个邻接结点
while(w != -1){ //当邻接结点存在时循环
if(! visited[w]) //如果没有访问过
depthFirstSearch(w, visited, vs); //以w为初始结点递归遍历
w = getNextNeighbor(v, w); //取下一个邻接结点
}
}