当前位置:   article > 正文

数据结构篇:图的遍历(一:深度优先遍历)

深度优先遍历

深度优先遍历,也称作深度优先搜索,缩写为DFS

深度优先遍历从某个顶点出发,访问此顶点,然后从v的未被访问的邻接点触发深度优先便利图,直至所有和v有路径想通的顶点都被访问到。

这样我们一定就访问到所有结点了吗,没有,可能还有的分支我们没有访问到,所以需要回溯(一般情况下都设置一个数组,来记录顶点是否访问到,如果访问到就不执行DFS算法,如果未被访问过就执行DFS算法)

以这张图为例

我们约定,在没有碰到重复顶点的情况下,优先选择右手边

那么按深度优先遍历就是:A B C D E F G H(此时这条线路已经走到尽头,可是还有一个I顶点没有遍历,所以回到G,发现G的邻接点都遍历过了,再回到F,发现F的邻接点也都遍历过了。。。直到D顶点,发现I这个顶点没有遍历,所以把I再遍历,继续回溯,最终回到起点A) I

落实到代码就是

  1. //访问标志的数组,为1表示访问过,为0表示未被访问
  2. int visted[100];
  1. //邻接表的深度优先遍历算法
  2. void AdjacencyList::DFS(GraphAdjList *G, int i) {
  3. EdgeNode *p;
  4. visted[i] = 1;
  5. cout << G->adjList[i].data << "--";
  6. p = G->adjList[i].firstedge;
  7. while (p)
  8. {
  9. if (!visted[p->adjvex])
  10. {
  11. //递归访问
  12. DFS(G, p->adjvex);
  13. }
  14. p = p->next;
  15. }
  16. }
  1. //邻接表的深度遍历操作
  2. void AdjacencyList::DFSTraverse(GraphAdjList *G) {
  3. //初始化所有顶点都没有访问过
  4. cout<<"深度优先遍历结果为:"<<endl;
  5. for (int i = 0; i < G->numVertexes; i++)
  6. {
  7. visted[i] = 0;
  8. }
  9. for (int i = 0; i < G->numVertexes; i++)
  10. {
  11. if (visted[i] == 0)
  12. {
  13. DFS(G, i);
  14. }
  15. }
  16. }

完整代码

  1. //
  2. // Created by 烟雨迷离半世殇 on 2018/11/21.
  3. //
  4. #include <iostream>
  5. using namespace std;
  6. //访问标志的数组,为1表示访问过,为0表示未被访问
  7. int visted[100];
  8. //边表结点
  9. typedef struct EdgeNode {
  10. //顶点对应的下标
  11. int adjvex;
  12. //指向下一个邻接点
  13. struct EdgeNode *next;
  14. } edgeNode;
  15. //顶点表结点
  16. typedef struct VertexNode {
  17. //顶点数据
  18. char data;
  19. //边表头指针
  20. edgeNode *firstedge;
  21. } VertexNode, AdjList[100];
  22. //集合
  23. typedef struct {
  24. AdjList adjList;
  25. //顶点数和边数
  26. int numVertexes, numEdges;
  27. } GraphAdjList;
  28. class AdjacencyList {
  29. public:
  30. void CreateALGraph(GraphAdjList *G);
  31. void ShowALGraph(GraphAdjList *G);
  32. void DFS(GraphAdjList *G, int i);
  33. void DFSTraverse(GraphAdjList *G);
  34. void Test();
  35. };
  36. void AdjacencyList::CreateALGraph(GraphAdjList *G) {
  37. int i, j, k;
  38. edgeNode *e;
  39. cout << "输入顶点数和边数" << endl;
  40. //输入顶点数和边数
  41. cin >> G->numVertexes >> G->numEdges;
  42. //读入顶点信息,建立顶点表
  43. for (i = 0; i < G->numVertexes; i++)
  44. {
  45. //输入顶点信息
  46. cin >> G->adjList[i].data;
  47. //将边表置为空表
  48. G->adjList[i].firstedge = NULL;
  49. }
  50. //建立边表(头插法)
  51. for (k = 0; k < G->numEdges; k++)
  52. {
  53. cout << "输入边(vi,vj)上的顶点序号" << endl;
  54. cin >> i >> j;
  55. e = new EdgeNode;
  56. e->adjvex = j;
  57. e->next = G->adjList[i].firstedge;
  58. G->adjList[i].firstedge = e;
  59. e = new EdgeNode;
  60. e->adjvex = i;
  61. e->next = G->adjList[j].firstedge;
  62. G->adjList[j].firstedge = e;
  63. }
  64. }
  65. void AdjacencyList::Test() {
  66. cout << "ALL IS OK." << endl;
  67. }
  68. void AdjacencyList::ShowALGraph(GraphAdjList *G) {
  69. for (int i = 0; i < G->numVertexes; i++)
  70. {
  71. cout << "顶点" << i << ": " << G->adjList[i].data << "--firstedge--";
  72. edgeNode *p = new edgeNode;
  73. p = G->adjList[i].firstedge;
  74. while (p)
  75. {
  76. cout << p->adjvex << "--Next--";
  77. p = p->next;
  78. }
  79. cout << "--NULL" << endl;
  80. }
  81. }
  82. void AdjacencyList::DFS(GraphAdjList *G, int i) {
  83. EdgeNode *p;
  84. visted[i] = 1;
  85. cout << G->adjList[i].data << "--";
  86. p = G->adjList[i].firstedge;
  87. while (p)
  88. {
  89. if (!visted[p->adjvex])
  90. {
  91. //递归访问
  92. DFS(G, p->adjvex);
  93. }
  94. p = p->next;
  95. }
  96. }
  97. void AdjacencyList::DFSTraverse(GraphAdjList *G) {
  98. //初始化所有顶点都没有访问过
  99. cout<<"深度优先遍历结果为:"<<endl;
  100. for (int i = 0; i < G->numVertexes; i++)
  101. {
  102. visted[i] = 0;
  103. }
  104. for (int i = 0; i < G->numVertexes; i++)
  105. {
  106. if (visted[i] == 0)
  107. {
  108. DFS(G, i);
  109. }
  110. }
  111. }
  112. int main() {
  113. AdjacencyList adjacencyList;
  114. GraphAdjList *GA = new GraphAdjList;
  115. adjacencyList.Test();
  116. adjacencyList.CreateALGraph(GA);
  117. adjacencyList.ShowALGraph(GA);
  118. adjacencyList.DFSTraverse(GA);
  119. return 0;
  120. }

以这张图为基准输入

运行结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/827410
推荐阅读
相关标签
  

闽ICP备14008679号