图的深度优先遍历

图的深度优先遍历

    图的深度遍历原则:

1 如果有可能,访问一个领接的未访问的节点,标记它,并把它放入栈中。

2 当不能执行规则 1 时,如果栈不为空,则从栈中弹出一个元素。

3 如果不能执行规则 1 和规则 2 时,则完成了遍历。

     设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。若发现顶点y已访问过,则重新

选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜

索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检

测过的边。上述过程直至从x出发的所有边都已检测过为止。

 

邻接表及逆邻接表的存储方法

1)定义

邻接表是图的一种链式存储结构。类似于树的孩子链表表示法。在邻接表中为图中每个顶点建立一个单链表,用单链表中的一个结点表示依附于该顶点的一条边(或表示以该顶点为弧尾的一条弧),称为边(或弧)结点。特征如下:

1) 为每个顶点建立一个单链表,

2) 第i个单链表中包含顶点Vi的所有邻接顶点。

把同一个顶点发出的边链接在同一个边链表中,链表的每一个结点代表一条边,叫做表结点(边结点),邻接点域adjvex保存与该边相关联的另一顶点的顶点下标 , 链域nextarc存放指向同一链表中下一个表结点的指针 ,数据域info存放边的权。边链表的表头指针存放在头结点中。头结点以顺序结构存储,其数据域data存放顶点信息,链域firstarc指向链表中第一个顶点。

9、深度优先算法,图的遍历 - 墨涵 - 墨涵天地

带权图的边结点中info保存该边上的权值。

顶点 Vi 的边链表的头结点存放在下标为 i 的顶点数组中。

在邻接表的边链表中,各个边结点的链入顺序任意,视边结点输入次序而定。

设图中有 n 个顶点,e 条边,则用邻接表表示无向图时,需要 n 个顶点结点,2e 个边结点;用邻接表表示有向图时,若不考虑逆邻接表,只需 n 个顶点结点,e 个边结点。

建立邻接表的时间复杂度为O(n*e)。若顶点信息即为顶点的下标,则时间复杂度为O(n+e)。

2)邻接表的示例及逆邻接表

9、深度优先算法,图的遍历 - 墨涵 - 墨涵天地

在有向图的邻接表中,第 i 个链表中结点的个数是顶点Vi的出度,表结点的adjvex存储的是以当前头结点为弧尾的弦。在所有链表中其邻接点域的值为i的结点的个数是顶点vi的入度。

在有向图的逆邻接表中,第 i 个链表中结点的个数是顶点Vi 的入度,表结点的adjvex存储的是以当前头结点为弧首的弦。

如下为带权图的邻接表:

9、深度优先算法,图的遍历 - 墨涵 - 墨涵天地

9、深度优先算法,图的遍历 - 墨涵 - 墨涵天地

 

 

深度优先遍历代码实现:

 

#include<iostream>
using namespace std;
int book[101],sum,n,e[101][101],l=0;
void dfs(int cur)
{
     int i;
     if(l==0) printf("%d",cur),l=1;
     else printf(" %d",cur);
     sum++;
     if(sum==n) return ;
     for(i=1;i<=n;i++)
     {
         if(e[cur][i]==1&&book[i]==0)
         {
             book[i]=1;
             dfs(i);
         }
     }
}
int main()
{
    int i,j,m,a,b;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            if(i==j) e[i][j]=0;
            else e[i][j]=99999999;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        e[a][b]=1;
        e[b][a]=1;
    }
    book[1]=1;
    dfs(1);
}

  

posted @ 2016-06-22 19:09  wxjor  阅读(1804)  评论(0编辑  收藏  举报