16 - 12 - 27 图的遍历-深度优先遍历(DFS)

来源:互联网 发布:avmoo最新域名2016 8 编辑:程序博客网 时间:2024/06/05 06:46

**深搜(DFS)与宽搜(WFS)—(deep_first_search)
1、深搜始终先访问靠右的节点,访问过的节点 做标记visited[0\1],直到所有节点都被标记为访问过(连通图)————递归过程。
2、对于非连通图,只需要对他的连通分量分别进行深度优先遍历。即在先前一个顶点进行过一次深度优先遍历后,若图中尚有顶点未被访问,则另选图中一个未曾被访问的节点作为起始点,重复上述过程,直到图中所有的顶点都被访问(被标记)

深度优先 -邻接矩阵

*如果我们用的的是邻接矩阵的方式,那么代码如下。

#define MAXVEX 100  ////最大顶点数typedef char VertexType;  //顶点类型typedef int EdgeType;  //权值类型#define INFINITY 65535 //用65535来表∞#define MAX 1000typedef struct {    VertexType vexs[MAXVEX];  //顶点表    EdgeType arc[MAXVEX][MAXVEX];  //邻接矩阵(边表)    int numVertexes,numEdges; //当前的顶点数和边数。}MGraph;typedef int Boolean;               /*Boolean是布尔类型,其值是FALSE或TRUE*/Boolean visited[MAX];   /*是否访问过?  : 标志数组*/void DFS(MGraph G,int i);    // 声明 void DFSTraverse(MGraph G)  /*邻接矩阵的深度遍历操作*/{    int i ;    for ( i = 0 ; i < G.numVertexes ; i++)        visited[i] == FALSE;  /*初始化所有顶点都未访问过*/    for (i = 0; i < G.numVertexes; i++)        if ( !visited[i] )   /*对未访问过的节点调用DFS*/            DFS( G , i ) ;     /*若是连通图*/}   void DFS(MGraph G,int i)   /*深搜递归算法*/{    int j;    visited[ i ] = TRUE;    //标记为访问过    printf(" %c   ",G.vexs[ i ]) ;        for( j = 0 ; j < G.numVertexes ; j++)        if(G.arc[i][j] == 1 && !visited[j] )            DFS(G,j) ;    /*对未访问的邻接顶点递归调用*/}

深度优先-邻接表

*如果我们用的的是邻接表的方式,那么代码如下。

typedef char VertexType;  //顶点类型typedef int EdgeType;  //权值类型#define INFINITY 65535  #define MAXVEX 100 //最大顶点数typedef struct node {   //边表节点    int adjvex;    //邻接点域    EdgeType weight;    struct node *next;  //链域,指向下一个邻接点。}EdgeNode ;typedef struct VertexNode { //顶点表节点。    VertexType data;    //顶点域存储定顶点信息。    EdgeNode *firstedge;  //边表头指针。}VertexNode,AdjList[MAXVEX];typedef struct {    AdjList adjlist;    int numVertexes , numEdges;  //图中当前顶点数和边数}GraphAdjList;//邻接表的实现void DFS(GraphAdjList GL,int i) ;   //声明;void DFSTraverse(GraphAdjList GL){    int i;    for(i = 0 ; i < GL->numVertexes ; i++)        visited[i] = FALSE;  /*初始化所有节点为未访问状态*/    for(i = 0 ; i<GL->numVertexes ; i++)        if(!visited[i])     // 1、            DFS( GL , i ) ;} //1、对未访问过的节点调用DFS函数void DFS(GraphAdjList GL,int i){    EdgeNode *p;    visited[ i ] = TRUE;   //标记为已访问    printf("%c\n", GL->adjlist[i].data);  //打印出顶点    p = GL->adjlist[i].firstedge;    while(p){        if ( !visited[ p->adjvex ] )            DFS(GL , p->adjvex);   /*对未访问的邻接顶点*/        p = p->next ;        }}

/邻接表的深度遍历操作/
总结: 对比两个不同存储结构的深度优先遍历算法,对于n个顶点e条边的图来说,邻接矩阵由于是二维数组,要查找每个顶点的邻接点需要访问矩阵中的所有元素因此都需要O(n*n)的时间,
而邻接表做存储结构时,寻找邻接点多需要的时间取决于顶点和边的数量,所以是O(n+e),显然对于点多边少的稀疏图来说,邻接表结构使得算法在时间效率上大大提高。

1 0