• 数据结构-Prim算法构造无向图的最小生成树


    引子:

    无向图如果是一个网,那么它的所有的生成树中必有一颗生成树的边的权值之和是最小的,我们称

    这颗权值和最小的树为:“最小生成树”(MST)。

    其中,一棵树的代价就是树中所有权值之和。

    而在现实中,最小生成树的概念可以用来解决很多实际问题,例如,在n个城市之间建立交通网,

    那么哪一条路径是最短的呢?就可以用最小生成树来解决。

    算法思想:

    设G = (V,E)为以连通网,其中V为顶点集合,E为带权边集合。

    设置两个新集合U和T:

    U用于存放最小生成树的顶点,T用于存放最小生成树的边。

    令集合的初值为:{u0}(假设构造最小生成树时,从顶点u0出发。)

    集合T的初值为{}。

    从所有u∈U,v∈V-U的边(u,v)中,选取最小权值的边(u0,v0),将顶点v0加入集合U中,将边

    (u0,v0)加入集合T中。

    如此不断重复,直到U = V,最小生成树构造完成,集合T中包含了最小生成树中的所有边。

    分析算法可知:

    为了实现Prim算法,需要一个辅助数组closedge以记录从U到V-U具有最小代价的边。

    对于closedge数组需要包含两个域:

    adjvex和lowcost,其中lowcost = 0表示若顶点v已在生成树上,用closedge.lowcost存放v与生成树

    上的另一个顶点的序号所构成边的权值。

    adjvex存放与该边相关联的生成树上的另一顶点的序号。

    算法生成图

    对于下面这个无向图例子来说:

                                                                                                                                                                                                     

    算法的执行过程如下:

    代码部分:

    1. #include
    2. #define MAX 100
    3. typedef struct Mgraph{
    4. char vertex[MAX];
    5. int arcs[MAX][MAX];
    6. int vexnum,arcnum;
    7. }Mgraph;
    8. typedef struct Closedge{
    9. char adjvex[MAX];
    10. int lowcost[MAX];
    11. }Closedge;
    12. int LocateVerTex(Mgraph *G,char v)
    13. {
    14. int k;
    15. for(k=0;kvexnum;k++)
    16. if(G->vertex[k] == v)
    17. return k;
    18. return -1;
    19. }
    20. void CreateMgraph(Mgraph *G)
    21. {
    22. int i,j,weight,adj1,adj2;
    23. char v1,v2;
    24. printf("请输入顶点数和边数:\n");
    25. scanf("%d %d",&G->vexnum,&G->arcnum);
    26. getchar();
    27. printf("请输入:{%d}个顶点:\n",G->vexnum);
    28. for(i=0;ivexnum;i++)
    29. scanf("%c",&G->vertex[i]);
    30. getchar();
    31. printf("请输入:{%d}条边:(格式如下:v1 v2 权值).\n",G->arcnum);
    32. for(i=0;ivexnum;i++){
    33. for(j=0;jvexnum;j++){
    34. G->arcs[i][j] = 9999;
    35. }
    36. }
    37. for(i=0;iarcnum;i++){
    38. scanf("%c %c %d",&v1,&v2,&weight);
    39. getchar();
    40. adj1 = LocateVerTex(G,v1);
    41. adj2 = LocateVerTex(G,v2);
    42. if(adj1 == -1 || adj2 == -1){
    43. printf("失败.\n");
    44. i = i - 1;
    45. continue;
    46. }
    47. else{
    48. G->arcs[adj1][adj2] = weight;
    49. G->arcs[adj2][adj1] = weight;
    50. printf("成功.\n");
    51. }
    52. }
    53. }
    54. int MiniNum(Closedge *closedge,Mgraph *G)
    55. {
    56. int j,p = 1,min = 999;
    57. for(j=0;jvexnum;j++){
    58. if(closedge->lowcost[j] != 0 && closedge->lowcost[j] < min){
    59. min = closedge->lowcost[j];
    60. p = j;
    61. }
    62. }
    63. return p;
    64. }
    65. void MiniTree_Prim(Mgraph *G,char u)
    66. {
    67. int i,j,k,num;
    68. k = LocateVerTex(G,u);
    69. Closedge closedge;
    70. for(i=0;ivexnum;i++){
    71. if(i!=k){
    72. closedge.adjvex[i] = u;
    73. closedge.lowcost[i] = G->arcs[k][i];
    74. }
    75. }
    76. closedge.lowcost[k] = 0;
    77. printf("最小生成树的各条边为:\n");
    78. for(i=1;ivexnum;i++){
    79. k = MiniNum(&closedge,G);
    80. printf("边:<%c,%c>,权值为{%d}:\n",closedge.adjvex[k],G->vertex[k],closedge.lowcost[k]);
    81. closedge.lowcost[k] = 0;
    82. for(j=0;jvexnum;j++){
    83. if(G->arcs[k][j] < closedge.lowcost[j]){
    84. closedge.adjvex[j] = G->vertex[k];
    85. closedge.lowcost[j] = G->arcs[k][j];
    86. }
    87. }
    88. }
    89. }
    90. int main()
    91. {
    92. Mgraph G;
    93. CreateMgraph(&G);
    94. MiniTree_Prim(&G,'A');
    95. return 0;
    96. }

    验证部分:

  • 相关阅读:
    appium
    torch、(三) Random sampling
    XSC63-300-S-CB、XSC80-400-S-CA、XSC100-700-S-LB方型气缸
    【Day18】多态(理解与应用)
    mysql多表查询
    flink学习
    [SWPU2019]Web1-1|SQL注入
    【软考】系统集成项目管理工程师(九)项目成本管理
    【C】高并发内存池设计
    CAD安装与经典模式设置
  • 原文地址:https://blog.csdn.net/zheshiyangyang/article/details/134274480