图——存储结构为邻接表表示的图的深度优先搜索递归算法详解

深度优先搜索的算法思想:

    设初始状态时图中的所有顶点都未被访问,则:

    (1):从图中某个顶点i出发,访问i; 然后找到i的一个邻接顶点i1;

    (2):从i1出发,深度优先搜索访问和i1相邻接且未被访问的所有顶点;

    (3):转(1),直到和i相邻接的所有顶点都被访问为止;

     (4):继续选取图中未被访问顶点j作为其实顶点,转(1),直到图中所有顶点都被访问为止;

图的深度优先搜索类似于二叉树的先序遍历。

图的拓扑 结构图及其邻接表表示的存储结构:

假设,从顶点2开始遍历这个图:

(1),访问顶点2;

扫描二维码关注公众号,回复: 5732800 查看本文章

(2)顶点2的第一个邻接顶点为1,所以访问顶点1;

(3)顶点1的第一个邻接顶点为0,所以访问顶点0;

(4)顶点0的第一个邻接顶点为1,因为1已经被访问过,所以访问这条链表上与1邻接的顶点3,顶点3没有被访问过,所以访问顶点3;

(5)顶点3的第一个邻接顶点为0,因为0已经被访问过,所以访问这条链表上与0邻接的顶点1,又顶点1被访问过,再次访问这条链表上与顶点1邻接的顶点2,又顶点2也被访问过,再次访问这条链表上与2邻接的顶点4,4没有别访问过,所以访问4;

至此,所有顶点都被访问完了,但是由于采用的是递归算法,所以这个算法还没有结束,需要继续回溯到首顶点。

(6)顶点4的第一个邻接顶点为0,被访问过,再次访问这条链表上与0邻接的顶点2,2被访问过,再次访问这条链表上与2顶点邻接的顶点3,顶点3已经被访问过;

(7)然后退回到访问顶点4的顶点3所在的第四条链表;

(8)然后退回到访问顶点3的顶点0所在的第一条链表,第一条链表中顶点3后面的顶点4还没有被访问,也要判断一下是否被访问;经过判断,该顶点已经被访问,这条链表已经访问完了,所以退回到访问顶点0所在的第二条链表;

(9)第二条链表中的顶点2和顶点3之前没有访问,所以判断一下是否被访问过,经过判断,这两个顶点都被访问了,所以退回到访问顶点1的顶点2所在第三条顶点;

(10)顶点2所在的第二条链表中的顶点3和顶点4,在之前都没有被访问,也要判断一下是否被访问,经过比较判断,这两个顶点都被访问了,所以就退回到顶点2;由于顶点2是初始访问的顶点,同时该图又是一个连通图,所以,至此,该图的访问正式结束了。

算法实现;

由算法思想可知,这是一个递归过程,因此,先设计一个从某个顶点为开始深度优先搜索的函数,便于调用。

在遍历整个图时,可以对图中的每一个为被访问的顶点执行所定义的函数。

typedef emnu {FALSE, TRUE} BOOLEAN;
BOOLEAN Visted[MAX_VEX];

void DFS(ALGraph *G, int v)
{
    LinkNode *p;
    Visited[v] = TRUE;
    visit(v);//访问顶点v
    p = G->AdjList[v].firstarc;//链表的第一个顶点
    while (p != NULL)
    {
        if (!Visited[p->adjvex])
        {
            DFS(G, p->ajdvex);
        }
        //从v的未访问过的邻接顶点出发深度优先搜索
        p = p->nextarc;
    }
}

//如果是一个非连通图,则使用这个函数
void DFS_traverse_Graph(ALGraph *G)
{
    int v;
    for (v = 0; v < G->vernum; v++)
    {
        Visited[v] = FALSE;//访问标志初始化
    }
    //p = G->AdjList[v].firstarc;
    for (v = 0; v < G->vexnum; v++)
    {
        if (!Visited[v])
            DFS(G, v);
    }
}

猜你喜欢

转载自blog.csdn.net/fu_jian_ping/article/details/88934843