第十一周项目二

来源:互联网 发布:socket编程 贪吃蛇 编辑:程序博客网 时间:2024/05/16 07:57
  1. /*  
  2. 烟台大学计算机学院  
  3.   
  4. 文件名称:2.cpp  
  5.   
  6. 作者:刘照京  
  7.   
  8. 完成日期:2017年11月30日  
  9.   
  10. 问题描述:Kruskal算法的验证 
  11.   
  12. 输入描述:无 
  13.   
  14. 输出描述:最小生成树的构成 
  15. 用到了graph.h 
  16.   
  17. */   
  18.   
  19.   
  20. #include <stdio.h>  
  21. #include <malloc.h>  
  22. #include "graph.h"  
  23. #define MaxSize 100  
  24. typedef struct  
  25. {  
  26.     int u;     //边的起始顶点  
  27.     int v;     //边的终止顶点  
  28.     int w;     //边的权值  
  29. } Edge;  
  30.   
  31. void InsertSort(Edge E[],int n) //对E[0..n-1]按递增有序进行直接插入排序  
  32. {  
  33.     int i,j;  
  34.     Edge temp;  
  35.     for (i=1; i<n; i++)  
  36.     {  
  37.         temp=E[i];  
  38.         j=i-1;              //从右向左在有序区E[0..i-1]中找E[i]的插入位置  
  39.         while (j>=0 && temp.w<E[j].w)  
  40.         {  
  41.             E[j+1]=E[j];    //将关键字大于E[i].w的记录后移  
  42.             j--;  
  43.         }  
  44.         E[j+1]=temp;        //在j+1处插入E[i]  
  45.     }  
  46. }  
  47.   
  48. void Kruskal(MGraph g)  
  49. {  
  50.     int i,j,u1,v1,sn1,sn2,k;  
  51.     int vset[MAXV];  
  52.     Edge E[MaxSize];    //存放所有边  
  53.     k=0;                //E数组的下标从0开始计  
  54.     for (i=0; i<g.n; i++)   //由g产生的边集E  
  55.         for (j=0; j<g.n; j++)  
  56.             if (g.edges[i][j]!=0 && g.edges[i][j]!=INF)  
  57.             {  
  58.                 E[k].u=i;  
  59.                 E[k].v=j;  
  60.                 E[k].w=g.edges[i][j];  
  61.                 k++;  
  62.             }  
  63.     InsertSort(E,g.e);      //采用直接插入排序对E数组按权值递增排序  
  64.     for (i=0; i<g.n; i++)   //初始化辅助数组  
  65.         vset[i]=i;  
  66.     k=1;    //k表示当前构造生成树的第几条边,初值为1  
  67.     j=0;    //E中边的下标,初值为0  
  68.     while (k<g.n)       //生成的边数小于n时循环  
  69.     {  
  70.         u1=E[j].u;  
  71.         v1=E[j].v;      //取一条边的头尾顶点  
  72.         sn1=vset[u1];  
  73.         sn2=vset[v1];   //分别得到两个顶点所属的集合编号  
  74.         if (sn1!=sn2)   //两顶点属于不同的集合  
  75.         {  
  76.             printf("  (%d,%d):%d\n",u1,v1,E[j].w);  
  77.             k++;                     //生成边数增1  
  78.             for (i=0; i<g.n; i++)   //两个集合统一编号  
  79.                 if (vset[i]==sn2)   //集合编号为sn2的改为sn1  
  80.                     vset[i]=sn1;  
  81.         }  
  82.         j++;               //扫描下一条边  
  83.     }  
  84. }  
  85.   
  86. int main()  
  87. {  
  88.     MGraph g;  
  89.     int A[6][6]=  
  90.     {  
  91.         {0,6,1,5,INF,INF},  
  92.         {6,0,5,INF,3,INF},  
  93.         {1,5,0,5,6,4},  
  94.         {5,INF,5,0,INF,2},  
  95.         {INF,3,6,INF,0,6},  
  96.         {INF,INF,4,2,6,0}  
  97.     };  
  98.     ArrayToMat(A[0], 6, g);  
  99.     printf("最小生成树构成:\n");  
  100.     Kruskal(g);  
  101.     return 0;  
  102. }  

运行结果:

学习心得:学会了最小生成树的克鲁斯卡尔算法。

原创粉丝点击