• 数据结构与算法特训365天—深度优先搜索


    一、知识点概述

           深度优先搜索(Depth First Search,DFS),是最常见的图搜索方法之一。深度优先搜索沿着一条路径一直走下去,无法进行时,回退到刚刚访问的结点,似不撞南墙不回头,不到黄河心不死。深度优先遍历是按照深度优先搜索的方式对图进行遍历。

    二、深度优先遍历秘籍

            后被访问的顶点,其邻接点先被访问

            根据深度优先遍历秘籍,后来先服务,可以借助于栈实现。递归本身就是使用栈实现的,因此使用递归方法更方便。

    三、算法步骤

    1. 初始化图中所有顶点未被访问;

    2. 从图中的某个顶点v出发,访问v并标记已访问;

    3. 依次检查v的所有邻接点w,如果w未被访问,则从w出发进行深度优先遍历(递归调用,重复2-3步)。

    四、算法实现

    1. void DFS_AM(AMGraph G, int v) //基于邻接矩阵的深度优先遍历
    2. {
    3. int w;
    4. cout<"\t";
    5. visited[v]=true;
    6. for(w=0; w//依次检查v的所有邻接点
    7. if(G.Edge[v][w] && !visited[w]) //v、w邻接而且w未被访问
    8. DFS_AM(G,w); //从w顶点开始递归深度优先遍历
    9. }
    1. void DFS_AL(ALGraph G,int v) //基于邻接表的深度优先遍历
    2. {
    3. int w;
    4. AdjNode *p;
    5. cout<"\t";
    6. visited[v]=true;
    7. p=G.Vex[v].first;
    8. while(p) //依次检查v的所有邻接点
    9. {
    10. w=p->v; //w为v的邻接点
    11. if(!visited[w]) //w未被访问
    12. DFS_AL(G,w); //从w出发,递归深度优先遍历
    13. p=p->next;
    14. }
    15. }
    1. void DFS_AL(ALGraph G)
    2. {
    3. for(int i=0; i
    4. if(!visited[i])
    5. DFS_AL(G,i);
    6. }

    五、完整代码

    5.1 基于邻接矩阵的深度优先遍历

    1. #include
    2. using namespace std;
    3. #define MaxVnum 100 //顶点数最大值
    4. bool visited[MaxVnum]; //访问标志数组,其初值为“false”
    5. typedef char VexType; //顶点的数据类型,根据需要定义 //typedef:专门起外号的
    6. typedef int EdgeType; //边上权值的数据类型,若不带权值的图,则为0或1
    7. typedef struct{
    8. VexType Vex[MaxVnum]; //顶点数组
    9. EdgeType Edge[MaxVnum][MaxVnum]; //二维数组
    10. int vexnum,edgenum; //顶点数,边数
    11. }AMGraph;
    12. int locatevex(AMGraph G,VexType x)
    13. {
    14. for (int i=0; i//查找顶点信息的下标
    15. if(x==G.Vex[i])
    16. return i;
    17. return -1; //没找到
    18. }
    19. void CreateAMGraph(AMGraph &G)
    20. {
    21. int i,j;
    22. VexType u, v;
    23. cout<<"请输入顶点数:"<
    24. cin>>G.vexnum;
    25. cout<<"请输入边数:"<
    26. cin>>G.edgenum;
    27. cout<<"请输入顶点信息:"<
    28. for(int i=0; i//输入顶点信息,存入顶点信息数组
    29. cin>>G.Vex[i];
    30. for(int i=0; i//初始化邻接矩阵所有值为0,如果是网,则初始化为无穷大
    31. for(int j=0; j
    32. G.Edge[i][j]=0;
    33. cout<<"请输入每条边依附的两个顶点:"<
    34. while(G.edgenum--)
    35. {
    36. cin>>u>>v;
    37. i=locatevex(G,u); //查找顶点u的存储下标
    38. j=locatevex(G,v); //查找顶点v的存储下标
    39. if(i!=-1&&j!=-1)
    40. G.Edge[i][j]=G.Edge[i][j]=1; //邻接矩阵储置1
    41. else
    42. {
    43. cout<<"讨厌!你个大笨居输错了啦!!!"<
    44. G.edgenum++; //本次输入不算
    45. }
    46. }
    47. }
    48. void print(AMGraph G) //输出邻接矩阵
    49. {
    50. cout<<"图的邻接矩阵为:"<
    51. for(int i=0; i,G.vexnum; i++)
    52. {
    53. for(int j=0; j
    54. cout<"\t";
    55. cout<
    56. }
    57. }
    58. void DFS_AM(AMGraph G, int v) //基于邻接矩阵的深度优先遍历
    59. {
    60. int w;
    61. cout<"\t";
    62. visited[v]=true;
    63. for(w=0; w//依次检查v的所有邻接点
    64. if(G.Edge[v][w] && !visited[w]) //v、w邻接而且w未被访问
    65. DFS_AM(G,w); //从w顶点开始递归深度优先遍历
    66. }
    67. int main()
    68. {
    69. int v;
    70. VexType c;
    71. AMGraph G;
    72. CreateAMGraph(G);
    73. print(G);
    74. cout<<"请输入连通图的起始点:"<
    75. cin>>c;
    76. v=locatevex(G,c); //查找顶点u的存储下标
    77. if(v!=-1)
    78. {
    79. cout<<"深度优先搜索遍历连通图结果:"<
    80. DFS_AM(G,v);
    81. }
    82. else
    83. cout<<"输出顶点信息出错!请重新输入!"<
    84. return 0;
    85. }

    5.2 基于邻接表的深度优先遍历

    1. #include
    2. using namespace std;
    3. const int MaxVnum=100; //顶点数最大值
    4. bool visited[MaxVnum]; //访问标志数组,其初值为“false”
    5. typedef char VexType; //顶点的数据类型为字符型
    6. typedef struct AdjNode{ //定义邻接点类型
    7. int v;
    8. struct AdjNode *next; //指向下一个邻接点
    9. }AdjNode;
    10. typedef struct VexNode{ //定义定点类型
    11. VexType data; //VerType为顶点的数据类型,根据需要定义
    12. AdjNode *first; //指向第一个邻接点
    13. }VerNode;
    14. typedef struct{ //定义邻接表类型
    15. VexNode Vex[MaxVnum];
    16. int vexnum,edgenum; //顶点数,边数
    17. }ALGraph;
    18. int locatevex(ALGraph G,VexType x)
    19. {
    20. for(int i=0; i
    21. if(x==G.Vex[i].data)
    22. return i;
    23. return -1; //没找到
    24. }
    25. void insertedge(ALGraph &G, int i, int j) //头插法插入一条边
    26. {
    27. AdjNode *s;
    28. s=new AdjNode;
    29. s->v-j;
    30. s->next=G.Vex[i].first;
    31. G.Vex[i].first=s;
    32. }
    33. void print(ALGraph G) //输出邻接表
    34. {
    35. cout<<"------邻接表如下------"<
    36. for(int i=0; i
    37. {
    38. AdjNode *t=G.Vex[i].first;
    39. cout<":";
    40. while(t!=NULL)
    41. {
    42. cout<<"["<v<<"] ";
    43. t=t->next;
    44. }
    45. cout<
    46. }
    47. }
    48. void CreateALGraph(ALGraph &G) //创建有向图邻接表
    49. {
    50. int i,j;
    51. VexType u,v;
    52. cout<<"请输入顶点数和边数:"<
    53. cin>>G.vexnum>>G.edgenum;
    54. cout<<"请输入顶点信息:"<
    55. for(i=0; i//输入顶点信息,存入顶点信息数组
    56. cin>>G.Vex[i].data;
    57. for(i=0; i
    58. G.Vex[i].first=NULL;
    59. cout<<"请依次输入每条边的两个顶点u,v"<
    60. while(G.edgenum--)
    61. {
    62. cin>>u>>v;
    63. i=locatevex(G,u); //查找顶点u的存储下标
    64. j=locatevex(G,v); //查找顶点v的存储下标
    65. if(i!=-1&&j!=-1)
    66. insertedge(G,i,j);
    67. else
    68. {
    69. cout<<"输入顶点信息错!请重新输入!"<
    70. G.edgenum++;//本次输入不算
    71. }
    72. }
    73. }
    74. void DFS_AL(ALGraph G,int v) //基于邻接表的深度优先遍历
    75. {
    76. int w;
    77. AdjNode *p;
    78. cout<"\t";
    79. visited[v]=true;
    80. p=G.Vex[v].first;
    81. while(p) //依次检查v的所有邻接点
    82. {
    83. w=p->v; //w为v的邻接点
    84. if(!visited[w]) //w未被访问
    85. DFS_AL(G,w); //从w出发,递归深度优先遍历
    86. p=p->next;
    87. }
    88. }
    89. void DFS_AL(ALGraph G)
    90. {
    91. for(int i=0; i
    92. if(!visited[i])
    93. DFS_AL(G,i);
    94. }
    95. int main()
    96. {
    97. ALGraph G;
    98. int v;
    99. VexType c;
    100. CreateALGraph(G);
    101. print(G);
    102. cout<<"请输入连通图的起始点:"<
    103. cin>>c;
    104. v=locatevex(G,c); //查找顶点u的存储下标
    105. if(v!=-1)
    106. {
    107. cout<<"深度优先搜索遍历连通图结果:"<
    108. DFS_AL(G,v);
    109. }
    110. else
    111. cout<<"输出顶点信息出错!请重新输入!"<
    112. return 0;
    113. }

  • 相关阅读:
    VUE3照本宣科——应用实例API与setup
    linux 中文乱码 解决方法
    AI变现之Gpts搞流量+赚钱
    疫情物资储藏库建设规划问题,使用matlab+cplex+yalmib求解
    C++ 设计模式 —— 组合模式
    nmap的用法大全
    Mysql数据库 8.SQL语言 外键约束
    代码随想录算法训练营第二十五天|216.组合总和III 17.电话号码的字母组合
    新手如何练习SQL?|掌握
    【故障公告】1个存储过程拖垮整个数据库
  • 原文地址:https://blog.csdn.net/weixin_53864463/article/details/132634781