当前位置:   article > 正文

深度优先搜索(DFS)

深度优先搜索

目录

一、DFS的基本概念

二、图的DFS

三、深度优先搜索的特点

四、实现DFS

五、DFS代码 

六、完整代码

七、运行结果


一、DFS的基本概念

        深度优先搜索(Depth-First Search,DFS)是一种常见的图遍历算法,用于在图或树等数据结构中探索所有可能的路径,以及查找特定目标(如寻找路径、判断连通性等)。DFS从一个起始顶点出发,沿着一条路径尽可能深入地访问顶点,直到不能继续为止,然后回溯到之前的顶点,继续尝试其他路径。这个过程通常使用递归来实现。      

二、图的DFS

        在图的DFS中,我们需要记录已经访问过的顶点,以避免无限循环。我们使用一个布尔数组来表示哪些顶点已经被访问过。从起始顶点开始,对于每个未访问的邻接顶点,我们递归地执行DFS。

三、深度优先搜索的特点

  • 深度优先搜索倾向于沿着一条路径尽可能深入,因此可能会在递归中达到最大深度。
  • 在实际应用中,DFS常用于查找路径、拓扑排序、连通性判断等问题。

四、实现DFS

  下图为一个示例图,我们将对这个图进行DFS遍历

五、DFS代码 

  1. //DFS算法
  2. bool visited[MAX_VERTICES]; //用于标记顶点是否被访问过,访问过为true
  3. void DFS(Graph G, int v) { //从顶点v出发,对图G进行深度优先遍历
  4. visit(G, v); //访问顶点v
  5. visited[v] = true; //标记已访问
  6. for (int w = getFirstNeighbor(G, v); w >= 0; w = getNextNeighbor(G, v,w)) {
  7. if (!visited[w]) { //w顶点没被访问
  8. DFS(G, w); //递归调用DFS
  9. }
  10. }
  11. }

六、完整代码

  1. #include<iostream>
  2. using namespace std;
  3. //邻接矩阵定义图
  4. #define MAX_VERTICES 100 //顶点数目最大值
  5. typedef char VertexType; //顶点的数据类型
  6. typedef int EdgeType; //带权图中边上权值的数据类型
  7. struct Graph {
  8. int num_vertices, num_edge; // 图当前顶点和边的数量
  9. VertexType vex[MAX_VERTICES]; //顶点表
  10. EdgeType adj_matrix[MAX_VERTICES][MAX_VERTICES]; // 邻接矩阵,边表
  11. };
  12. //初始化
  13. void init_graph(Graph* graph, int num_vertices) {
  14. graph->num_vertices = num_vertices;
  15. graph->num_edge = 0;
  16. // 初始化邻接矩阵,初始值都为0(表示没有边)
  17. for (int i = 0; i < num_vertices; ++i) {
  18. //顶点数据赋值
  19. graph->vex[i] = 'a' + i;
  20. //邻接矩阵初始化
  21. for (int j = 0; j < num_vertices; ++j) {
  22. graph->adj_matrix[i][j] = 0;
  23. }
  24. }
  25. }
  26. //判断是否存在某条边(无向图)
  27. bool is_edge(Graph* graph, int source, int destination) {
  28. return graph->adj_matrix[source][destination] != 0 ||
  29. graph->adj_matrix[destination][source] != 0;
  30. }
  31. // 添加边,将邻接矩阵中对应的位置设为1(或边的权重值)
  32. void add_edge(Graph* graph, int source, int destination, int weight) {
  33. if (!is_edge(graph, source, destination)) {//不存在要添加的这条边
  34. graph->adj_matrix[source][destination] = weight;
  35. graph->adj_matrix[destination][source] = weight; // 对于无向图,需要设置对称位置
  36. graph->num_edge++;
  37. }
  38. else {
  39. cout << "此边已存在,不需要添加" << endl;
  40. }
  41. }
  42. //访问顶点
  43. void visit(Graph G, int v) { //访问顶点,这里是打印
  44. cout << G.vex[v];
  45. }
  46. // 求顶点v的第一个邻接点
  47. int getFirstNeighbor(Graph G, int v) {
  48. if (v >= 0 && v < G.num_vertices) {
  49. for (int i = 0; i < G.num_vertices; ++i) {
  50. if (G.adj_matrix[v][i] != 0) {
  51. return i;
  52. }
  53. }
  54. }
  55. return -1; // 顶点x没有邻接点或顶点索引无效
  56. }
  57. // 求顶点v的下一个邻接点
  58. int getNextNeighbor(Graph G, int v, int w) {
  59. if (v >= 0 && v < G.num_vertices) {
  60. for (int i = w + 1; i < G.num_vertices; ++i) {
  61. if (G.adj_matrix[v][i] != 0) {
  62. return i;
  63. }
  64. }
  65. }
  66. return -1; // 顶点x没有除y以外的下一个邻接点或顶点索引无效
  67. }
  68. //DFS算法
  69. bool visited[MAX_VERTICES]; //用于标记顶点是否被访问过,访问过为true
  70. void DFS(Graph G, int v) { //从顶点v出发,对图G进行深度优先遍历
  71. visit(G, v); //访问顶点v
  72. visited[v] = true; //标记已访问
  73. for (int w = getFirstNeighbor(G, v); w >= 0; w = getNextNeighbor(G, v, w)) {
  74. if (!visited[w]) { //w顶点没被访问
  75. DFS(G, w); //递归调用DFS
  76. }
  77. }
  78. }
  79. //DFSTraverse对图G进行广度优先遍历
  80. void DFSTraverse(Graph G) {
  81. for (int i = 0; i < G.num_vertices; i++) {
  82. visited[i] = false; //初始化标记数组
  83. }
  84. //无向图连通图任意一个顶点调用一次DFS即可访问到全部顶点
  85. DFS(G, 0); //从a开始
  86. //无向图若有多个连通分量,则每个连通分量都调用一次DFS
  87. //有向图调用一次DFS或者BFS不一定可以访问到所有顶点,得看它是不是强连通的
  88. }
  89. int main() {
  90. //创建一个图
  91. Graph G;
  92. Graph* graph = &G;
  93. //初始化
  94. init_graph(graph, 6);
  95. //添加边
  96. add_edge(graph, 0, 1, 1);//a-b
  97. add_edge(graph, 0, 2, 1);//a-c
  98. add_edge(graph, 0, 4, 1);//a-e
  99. add_edge(graph, 1, 4, 1);//e-b
  100. add_edge(graph, 4, 3, 1);//e-d
  101. add_edge(graph, 4, 5, 1);//e-f
  102. add_edge(graph, 3, 5, 1);//d-f
  103. //打印一下邻接矩阵
  104. cout << "所创建的图的邻接矩阵:" << endl;
  105. for (int i = 0; i < G.num_vertices; i++) {
  106. for (int j = 0; j < G.num_vertices; j++) {
  107. cout << G.adj_matrix[i][j];
  108. }
  109. cout << endl;
  110. }
  111. cout << endl;
  112. //DFS
  113. cout << "DFS遍历结果为:";
  114. DFSTraverse(G);
  115. return 0;
  116. }

七、运行结果

  完全没问题!!!!

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

闽ICP备14008679号