• 图的遍历-DFS,BFS(代码详解)


    前言

            大家好,今天给大家带来的是图遍历的算法,DFS(深度优先遍历),BFS(广度优先遍历)。这两个算法是比较重要和常用的算法,但是在图中的实现只是最基本的操作,要是想完全掌握,还是需要去多练题。对应相关题目链接点击这里刷算法相关题目

    目录

    前言

    图的定义

    图的相关术语

     图的创建(邻接矩阵)---结构体

      图的创建(邻接矩阵)---邻接矩阵的创建

    图的创建(邻接表)---结构体

     图的创建(邻接表)---邻接表的创建

     对邻接矩阵进行深度优先遍历

      对邻接矩阵进行广度优先遍历

    对邻接表进行深度优先遍历 

     对邻接表进行广度优先遍历 

    整体代码

    结果展示

    结束语

    图的定义

            图由顶点集V(G)边集E(G)组成,记为G=(V,E)。其中E(G)是边的有限集合,边是顶点的无序对(无向图)或有序对(有向图)。对于有向图来说,E(G)是有向边(也称弧(Arc))的有限集合,弧是顶点的有序对,记为v、w是顶点,v为弧尾(箭头根部),w为弧头(箭头处)。对于无向图来说,E(G)是边的有限集合,边是顶点的无序对,记为(v, w)或者(w, v),并且(v, w)=(w,v)。

    图的相关术语

    ①顶点(Vertex):图中的数据元素。

    ②顶点v的度:与v相关联的边的数目;

    ③顶点v的出度:以v为起点有向边数;

    ④顶点v的入度:以v为终点有向边数。

    ⑤边:顶点之间的逻辑关系用边来表示,边集可以是空的。

    ⑥无向边(Edge):若顶点V1到V2之间的边没有方向,则称这条边为无向边。

    ⑦无向图(Undirected graphs):图中任意两个顶点之间的边都是无向边。(A,D)=(D,A)

    ⑧有向边:若从顶点V1到V2的边有方向,则称这条边为有向边,也称弧(Arc)。用表示,V1为狐尾(Tail),V2为弧头(Head)。(V1,V2)≠(V2,V1)。

    ⑨有向图(Directed graphs):图中任意两个顶点之间的边都是有向边。

                                  注意:无向边用“()”,而有向边用“< >”表示。

    ⑩简单图:图中不存在顶点到其自身的边,且同一条边不重复出现。

    ⑪无向完全图:无向图中,任意两个顶点之间都存在边。

    ⑫有向完全图:有向图中,任意两个顶点之间都存在方向互为相反的两条弧。

    ⑬稀疏图:有很少条边。

    ⑭稠密图:有很多条边。

    ⑮权(Weight):与图的边或弧相关的数。

    ⑯网(Network):带权的图。

    ⑰连通图:图中任意两个顶点都是连通的。

    ⑱极大连通子图:该子图是G连通子图,将G的任何不在该子图的顶点加入,子图将不再连通。

    ⑲极小连通子图:该子图是G的连通子图,在该子图中删除任何一条边,子图都将不再连通。

     图的创建(邻接矩阵)---结构体

    1. typedef struct
    2. {
    3. //用来存放顶点
    4. int vexs[MAX];
    5. //二维数组:用来存放两点之间的关系
    6. int arcs[MAX][MAX];
    7. //图的顶点数和边数
    8. int vexsum, arcsnum;
    9. }AMGraph,*StrAMGraph;

      图的创建(邻接矩阵)---邻接矩阵的创建

    1. int locate(AMGraph&G, int n)
    2. {
    3. for (int i = 0; i < G.vexsum; i++)
    4. {
    5. if (G.vexs[i] == n)
    6. {
    7. return i;
    8. }
    9. }
    10. }
    11. //创建邻接矩阵
    12. void Creat(AMGraph&G)
    13. {
    14. int v1 = 0, v2 = 0, w = 0;
    15. cin >> G.vexsum >> G.arcsnum;
    16. for (int i = 0; i < G.vexsum; i++)
    17. {
    18. cin >> G.vexs[i];
    19. }
    20. for (int i = 0; i < G.vexsum; i++)
    21. {
    22. for (int j = 0; j < G.vexsum; j++)
    23. {
    24. G.arcs[i][j] = 0;
    25. }
    26. }
    27. for (int k = 0; k < G.arcsnum; k++)
    28. {
    29. cin >> v1 >> v2 >> w;
    30. int i = locate(G, v1);
    31. int j = locate(G, v2);
    32. G.arcs[i][j] = w;
    33. }
    34. }

    图的创建(邻接表)---结构体

    1. typedef struct ArcNode
    2. {
    3. int Adjust;
    4. struct ArcNode *next;
    5. }AcrNode,*StrAcrNode;
    6. typedef struct
    7. {
    8. int data;
    9. StrAcrNode next;
    10. }HeadNode, *StrHeadNode;
    11. typedef struct
    12. {
    13. HeadNode arr[MAX];
    14. int acsrnum, vexsnum;
    15. }ALGraph, *StrALGraph;

     图的创建(邻接表)---邻接表的创建

    1. int locate1(ALGraph&G, int n)
    2. {
    3. for (int i = 0; i < G.vexsnum; i++)
    4. {
    5. if (G.arr[i].data == n)
    6. {
    7. return i;
    8. }
    9. }
    10. }
    11. void CreatALGraph(ALGraph&G)
    12. {
    13. int v1 = 0, v2 = 0, w = 0;
    14. cin >> G.vexsnum >> G.acsrnum;
    15. for (int i = 0; i < G.vexsnum; i++)
    16. {
    17. cin >> G.arr[i].data;
    18. G.arr[i].next = NULL;
    19. }
    20. for (int k = 0; k < G.acsrnum; k++)
    21. {
    22. cin >> v1 >> v2;
    23. int i = locate1(G, v1);
    24. int j = locate1(G, v2);
    25. StrAcrNode p1;
    26. p1 = new AcrNode;
    27. p1->next = G.arr[i].next;
    28. }
    29. }

     对邻接矩阵进行深度优先遍历

    1. //对邻接矩阵进行深度优先遍历
    2. void DFS(AMGraph&G, int n)
    3. {
    4. cout << G.vexs[n] << " ";
    5. visit[n] = 1;
    6. for (int i = 0; i < G.vexsum; i++)
    7. {
    8. if (G.arcs[n][i] != 1 && visit[i] != 1)
    9. {
    10. DFS(G, G.arcs[n][i]);
    11. }
    12. }
    13. }

      对邻接矩阵进行广度优先遍历

    1. queue<int> qu;
    2. //对邻接矩阵进行广度优先遍历
    3. void BFS(AMGraph&G, int n)
    4. {
    5. cout << G.vexs[n] << " ";
    6. qu.push(n);
    7. while (!qu.empty())
    8. {
    9. int m = qu.front();
    10. qu.pop();
    11. for (int i = 0; i < G.vexsum; i++)
    12. {
    13. if (visit[i] != 1 && G.arcs[m][i] != 1)
    14. {
    15. cout << G.vexs[i] << " ";
    16. visit[i] = 1;
    17. qu.push(i);
    18. }
    19. }
    20. }
    21. }

    对邻接表进行深度优先遍历 

    1. void DFS1(ALGraph&G, int n)
    2. {
    3. cout << G.arr[n].data << " ";
    4. visit3[n] = 1;
    5. StrAcrNode p1;
    6. p1 = G.arr[n].next;
    7. while (p1)
    8. {
    9. int w = p1->Adjust;
    10. if (visit3[w] != 1)
    11. {
    12. DFS1(G, w);
    13. }
    14. p1 = p1->next;
    15. }
    16. }
    17. queue<int> qu1;

     对邻接表进行广度优先遍历 

    1. queue<int> qu1;
    2. void BFS(ALGraph&G, int n)
    3. {
    4. cout << G.arr[n].data << " ";
    5. visit4[n] = 1;
    6. qu1.push(n);
    7. StrAcrNode p1;
    8. p1 = G.arr[n].next;
    9. while (!qu1.empty())
    10. {
    11. qu1.pop();
    12. int w = p1->Adjust;
    13. while (p1)
    14. {
    15. if (visit4[w] != 1)
    16. {
    17. qu1.push(w);
    18. visit4[w] = 1;
    19. }
    20. p1 = p1->next;
    21. }
    22. }
    23. }

    整体代码

    1. #include
    2. #include
    3. using namespace std;
    4. const int MAxInt = 10;
    5. int visit[MAxInt];
    6. typedef struct
    7. {
    8. int vexs[MAxInt];
    9. int arcs[MAxInt][MAxInt];
    10. int arcnum, vexsnum;
    11. }AMGraph;
    12. int locate(AMGraph&G, int n)
    13. {
    14. for (int i = 0; i < G.vexsnum; i++)
    15. {
    16. if (G.vexs[i] == n)
    17. {
    18. return i;
    19. }
    20. }
    21. }
    22. void Creat(AMGraph&G)
    23. {
    24. int v1 = 0, v2 = 0, w = 0;
    25. cin >> G.vexsnum >> G.arcnum;
    26. for (int i = 0; i < G.vexsnum; i++)
    27. {
    28. cin >> G.vexs[i];
    29. }
    30. for (int i = 0; i < G.vexsnum; i++)
    31. {
    32. for (int j = 0; j < G.vexsnum; j++)
    33. {
    34. G.arcs[i][j] = MAxInt;
    35. }
    36. }
    37. for (int k = 0; k < G.arcnum; k++)
    38. {
    39. cin >> v1 >> v2 >> w;
    40. int i = locate(G, v1);
    41. int j = locate(G, v2);
    42. G.arcs[i][j] = w;
    43. G.arcs[j][i] = w;
    44. }
    45. }
    46. queue<int> qu;
    47. void BFS(AMGraph G, int v)
    48. {
    49. cout << G.vexs[v];
    50. qu.push(v);
    51. visit[v] = 1;
    52. while (!qu.empty())
    53. {
    54. int w = qu.front();
    55. qu.pop();
    56. for (int i = 0; i < G.vexsnum; i++)
    57. {
    58. if (visit[i] != 1 && G.arcs[w][i] != MAxInt)
    59. {
    60. cout << G.vexs[i] << " ";
    61. visit[i] = 1;
    62. qu.push(i);
    63. }
    64. }
    65. }
    66. }
    67. int main()
    68. {
    69. AMGraph G;
    70. Creat(G);
    71. cout << "对图进行广度优先遍历的结果为" << endl;
    72. BFS(G, 1);
    73. return 0;
    74. }

    注意 :这里的代码是创建一个邻接矩阵来对图进行广度优先遍历,对图进行深度优先遍历以及临界表实现对图进行广度优先遍历,对图进行深度优先遍历大家都可以通过上面的代码块进行自由组合实现,这里就不进行一一实现。

    结果展示

    结束语

            到了这里今天的内容就全部结束了,希望能够给大家带来帮助,最后大家可以进入该链接进行练习DFS和BFS相关的题目点击这里刷算法相关题目 

  • 相关阅读:
    c++实现键盘hook
    线程池的4种拒绝策略
    深度学习入门之GRU
    SQL Server重置自增序列初始值
    Golang 基础之基础语法梳理 (三)
    java毕业设计中山乡村文化旅游网络平台Mybatis+系统+数据库+调试部署
    git使用---本地目录初始化关联远程仓库
    Fastjson反序列化漏洞
    消防设备电源监控系统在高层民用建筑内的应用
    Linux/shell 判断设备文件(/dev)是否存在
  • 原文地址:https://blog.csdn.net/weixin_64067830/article/details/125965460