图的遍历操作

图的遍历操作分为广度优先遍历和深度优先遍历。

对于连通图而言,从某个顶点出发是一定能够到达任意一个顶点的。

对于非连通图,从某个顶点出发不一定能走完所有的顶点,但是我们同样可以将连通图的方法应用到非连通图:

只需要将图中的每个顶点都作为初始顶点进行遍历就可以访问到所有的顶点。对于已经访问过的点我们可以进行标记,已访问过的点就不会在重复访问。

所有这里我们主要考虑连通图的遍历。

1、广度优先遍历

图的广度优先遍历和树的层序遍历相似,都需要借助队列来完成。

具体操作如下

1、访问初始顶点 v ,并将它标记为已访问;

2、将顶点 v 入队列

3、如果队列非空,获取队头元素 u ;如果队列为空算法结束

4、查找 u 的第一个邻接顶点 w ,如果 w 存在, 

    如果 w 未被访问,访问w,并标记 w 为已访问,然后将 w 入队列;

    如果 w 已经被访问, 查找 u 的下一个邻接顶点,重复 步骤 4

  如果 w 不存在,返回到步骤 3。

 

伪代码可以如下所示: 

//连通图广度优先遍历伪代码
BFS(Gragh G, int v)
{
    Visit(v);           //访问初始顶点
    visited[v] = 1;     //标记初始顶点已经被访问
    QueueAppend(queue, v); //将初始顶点入队列
    while(queueNotEmpty(queue)) //如果队列为空表示所有元素都访问完成,结束算法
    {
        QueueDelete(queue, u); //获取队头元素u
        w = GetFirstVex(G,u); //获取u的第一个邻接顶点
        while(w != NULL) //如果 w 存在, 则首先循环将u的所有邻接顶点访问完成
        {
            if(visited[w] != 1) //如果u的第一个邻接顶点 w 没有被访问
            {
                Visit(w);    //访问w
                visited[w] = 1; //标记队头元素 w 已经被访问
                QueueAppend(queue,w); //将 w 入队列
            }
            w = getNextVex(G,u,w); //获取u的下一个邻接顶点
        }
    }
}

 

2、深度优先遍历

图的深度优先遍历是指在图的所有邻接顶点中,每次都在访问玩当前顶点后,首先访问当前顶点的第一个邻接顶点。

深度优先遍历可以设计成递归算法。

具体操作如下

1、访问初始顶点 v ,并标记它为已访问。

2、查找 v 的第一个邻接顶点 u 。如果 u 存在

    如果 u 未被访问, 访问 u,并标记为访问状态,继续深度递归遍历 u 。

    如果 u 已经被访问,查找 v 的下一个邻接顶点,重复步骤2

  如果 u 不存在,结束算法。

伪代码如下:

//连通图的深度优先遍历
DFS(Gragh G, int v)
{
    if(v == NULL) return;
    Visit(v);           //访问初始顶点
    visited[v] = 1;     //标记初始顶点已经被访问
    u = GetFirstVex(G,v); //获取 v 的第一个邻接顶点
    while(u != NULL)
    {
        if(visited[u] != 1) //第一个邻接顶点没有被访问
        {
            DFS(G,u); //递归访问,直到深度遍历完成v的第一个邻接顶点
        }
         u = getNextVex(G,v,u); //获取下一个邻接顶点
    }
}

具体的代码可以查看我的github

 

posted on 2018-11-13 12:54  猫咪大王  阅读(261)  评论(0)    收藏  举报