• 深度优先遍历
    • 基本思想

    深度优先遍历

    基本思想

    • 从图G中某个顶点vi出发,访问vi,然后选择一个与vi相邻且没有被访问过的顶点v访问,再从v出发选择一个与v相邻且未被访问的顶点vj访问,依次访问。

    • 如果当前已被访问的顶点的所有邻接顶点都已被访问,则回退到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点w,从w出发按相同的方法继续遍历,直到所有的顶点都被访问到。

    1. #include <stdio.h>
    2. #include <malloc.h>
    3. #include <string.h>
    4. #define MAXVEX 100
    5. typedef char VertexType[3]; /*定义VertexType为char数组类型*/
    6. typedef struct vertex
    7. {
    8. int adjvex; /*顶点编号*/
    9. VertexType data; /*顶点的信息*/
    10. } VType; /*顶点类型*/
    11. typedef struct graph
    12. {
    13. int n,e; /*n为实际顶点数,e为实际边数*/
    14. VType vexs[MAXVEX]; /*顶点集合*/
    15. int edges[MAXVEX][MAXVEX]; /*边的集合*/
    16. } AdjMatix; /*图的邻接矩阵类型*/
    17. typedef struct edgenode
    18. {
    19. int adjvex; /*邻接点序号*/
    20. int value; /*边的权值*/
    21. struct edgenode *next; /*下一条边的顶点*/
    22. } ArcNode; /*每个顶点建立的单链表中结点的类型*/
    23. typedef struct vexnode
    24. {
    25. VertexType data; /*结点信息*/
    26. ArcNode *firstarc; /*指向第一条边结点*/
    27. } VHeadNode; /*单链表的头结点类型*/
    28. typedef struct
    29. {
    30. int n,e; /*n为实际顶点数,e为实际边数*/
    31. VHeadNode adjlist[MAXVEX]; /*单链表头结点数组*/
    32. } AdjList; /*图的邻接表类型*/
    33. void DispAdjList(AdjList *G)
    34. {
    35. int i;
    36. ArcNode *p;
    37. printf("图的邻接表表示如下:\n");
    38. for (i=0;i<G->n;i++)
    39. {
    40. printf(" [%d,%3s]=>",i,G->adjlist[i].data);
    41. p=G->adjlist[i].firstarc;
    42. while (p!=NULL)
    43. {
    44. printf("(%d,%d)->",p->adjvex,p->value);
    45. p=p->next;
    46. }
    47. printf("∧\n");
    48. }
    49. }
    50. void MatToList(AdjMatix g,AdjList *&G) /*例6.3算法:将邻接矩阵g转换成邻接表G*/
    51. {
    52. int i,j;
    53. ArcNode *p;
    54. G=(AdjList *)malloc(sizeof(AdjList));
    55. for (i=0;i<g.n;i++) /*给邻接表中所有头结点的指针域置初值*/
    56. {
    57. G->adjlist[i].firstarc=NULL;
    58. strcpy(G->adjlist[i].data,g.vexs[i].data);
    59. }
    60. for (i=0;i<g.n;i++) /*检查邻接矩阵中每个元素*/
    61. for (j=g.n-1;j>=0;j--)
    62. if (g.edges[i][j]!=0) /*邻接矩阵的当前元素不为0*/
    63. {
    64. p=(ArcNode *)malloc(sizeof(ArcNode));/*创建一个结点*p*/
    65. p->value=g.edges[i][j];p->adjvex=j;
    66. p->next=G->adjlist[i].firstarc; /*将*p链到链表后*/
    67. G->adjlist[i].firstarc=p;
    68. }
    69. G->n=g.n;G->e=g.e;
    70. }
    71. int visited[MAXVEX];
    72. void DFS(AdjList *g,int vi) /*对邻接表G从顶点vi开始进行深度优先遍历*/
    73. {
    74. ArcNode *p;
    75. printf("%d ",vi); /*访问vi顶点*/
    76. visited[vi]=1; /*置已访问标识*/
    77. p=g->adjlist[vi].firstarc; /*找vi的第一个邻接点*/
    78. while (p!=NULL) /*找vi的所有邻接点*/
    79. {
    80. if (visited[p->adjvex]==0)
    81. DFS(g,p->adjvex); /*从vi未访问过的邻接点出发深度优先搜索*/
    82. p=p->next; /*找vi的下一个邻接点*/
    83. }
    84. }
    85. void DFS1(AdjList *G,int vi) /*非递归深度优先遍历算法*/
    86. {
    87. ArcNode *p;
    88. ArcNode *St[MAXVEX];
    89. int top=-1,v;
    90. printf("%d ",vi); /*访问vi顶点*/
    91. visited[vi]=1; /*置已访问标识*/
    92. top++; /*将初始顶点vi的firstarc指针进栈*/
    93. St[top]=G->adjlist[vi].firstarc;
    94. while (top>-1) /*栈不空循环*/
    95. {
    96. p=St[top];top--; /*出栈一个顶点为当前顶点*/
    97. while (p!=NULL) /*循环搜索其相邻顶点*/
    98. {
    99. v=p->adjvex; /*取相邻顶点的编号*/
    100. if (visited[v]==0) /*若该顶点未访问过*/
    101. {
    102. printf("%d ",v); /*访问v顶点*/
    103. visited[v]=1; /*置访问标识*/
    104. top++; /*将该顶点的第1个相邻顶点进栈*/
    105. St[top]=G->adjlist[v].firstarc;
    106. break; /*退出当前顶点的搜索*/
    107. }
    108. p=p->next; /*找下一个相邻顶点*/
    109. }
    110. }
    111. }
    112. void main()
    113. {
    114. int i,j;
    115. AdjMatix g;
    116. AdjList *G;
    117. int a[5][5]={ {0,1,0,1,0},{1,0,1,0,0},{0,1,0,1,1},{1,0,1,0,1},{0,0,1,1,0} };
    118. char *vname[MAXVEX]={"a","b","c","d","e"};
    119. g.n=5;g.e=12; /*建立图6.1(a)的无向图,每1条无向边算为2条有向边*/
    120. for (i=0;i<g.n;i++)
    121. strcpy(g.vexs[i].data,vname[i]);
    122. for (i=0;i<g.n;i++)
    123. for (j=0;j<g.n;j++)
    124. g.edges[i][j]=a[i][j];
    125. MatToList(g,G); /*生成邻接表*/
    126. DispAdjList(G); /*输出邻接表*/
    127. for (i=0;i<g.n;i++) visited[i]=0; /*顶点标识置初值*/
    128. printf("从顶点0的深度优先遍历序列:\n");
    129. printf(" 递归算法:");DFS(G,0);printf("\n");
    130. for (i=0;i<g.n;i++) visited[i]=0; /*顶点标识置初值*/
    131. printf(" 非递归算法:");DFS1(G,0);printf("\n");
    132. }