1.普里姆算法

  1. // Prim算法生成最小生成树
  2. void MiniSpanTree_Prim(MGraph G)
  3. {
  4. int min, i, j, k;
  5. int adjvex[MAXVEX]; // 保存相关顶点下标
  6. int lowcost[MAXVEX]; // 保存相关顶点间边的权值
  7. lowcost[0] = 0; // V0作为最小生成树的根开始遍历,权值为0
  8. adjvex[0] = 0; // V0第一个加入
  9. // 初始化操作
  10. for( i=1; i < G.numVertexes; i++ )
  11. {
  12. lowcost[i] = G.arc[0][i]; // 将邻接矩阵第0行所有权值先加入数组
  13. adjvex[i] = 0; // 初始化全部先为V0的下标
  14. }
  15. // 真正构造最小生成树的过程
  16. for( i=1; i < G.numVertexes; i++ )
  17. {
  18. min = INFINITY; // 初始化最小权值为65535等不可能数值
  19. j = 1;
  20. k = 0;
  21. // 遍历全部顶点
  22. while( j < G.numVertexes )
  23. {
  24. // 找出lowcost数组已存储的最小权值
  25. if( lowcost[j]!=0 && lowcost[j] < min )
  26. {
  27. min = lowcost[j];
  28. k = j; // 将发现的最小权值的下标存入k,以待使用。
  29. }
  30. j++;
  31. }
  32. // 打印当前顶点边中权值最小的边
  33. printf("(%d,%d)", adjvex[k], k);
  34. lowcost[k] = 0; // 将当前顶点的权值设置为0,表示此顶点已经完成任务,进行下一个顶点的遍历
  35. // 邻接矩阵k行逐个遍历全部顶点
  36. for( j=1; j < G.numVertexes; j++ )
  37. {
  38. if( lowcost[j]!=0 && G.arc[k][j] < lowcost[j] )
  39. {
  40. lowcost[j] = G.arc[k][j];
  41. adjvex[j] = k;
  42. }
  43. }
  44. }
  45. }

2.克鲁斯卡尔算法

  1. int Find(int *parent, int f)
  2. {
  3. while( parent[f] > 0 )
  4. {
  5. f = parent[f];
  6. }
  7. return f;
  8. }
  9. // Kruskal算法生成最小生成树
  10. void MiniSpanTree_Kruskal(MGraph G)
  11. {
  12. int i, n, m;
  13. Edge edges[MAGEDGE]; // 定义边集数组
  14. int parent[MAXVEX]; // 定义parent数组用来判断边与边是否形成环路
  15. for( i=0; i < G.numVertexes; i++ )
  16. {
  17. parent[i] = 0;
  18. }
  19. for( i=0; i < G.numEdges; i++ )
  20. {
  21. n = Find(parent, edges[i].begin); // 4 2 0 1 5 3 8 6 6 6 7
  22. m = Find(parent, edges[i].end); // 7 8 1 5 8 7 6 6 6 7 7
  23. if( n != m ) // 如果n==m,则形成环路,不满足!
  24. {
  25. parent[n] = m; // 将此边的结尾顶点放入下标为起点的parent数组中,表示此顶点已经在生成树集合中
  26. printf("(%d, %d) %d ", edges[i].begin, edges[i].end, edges[i].weight);
  27. }
  28. }
  29. }

无论是普里姆算法(Prim)还是克鲁斯卡尔算法(Kruskal),他们考虑问题的出发点都是:为使生成树上边的权值之和达到最小,则应使生成树中每一条边的权值尽可能的小。
普里姆算法是以某顶点为起点,逐步找各个顶点上最小权值的边来构建最小生成树的。
克鲁斯卡尔算法是我们从边出发,因为权值是在边上嘛,直接去找最小权值的边来构建生成树是自然的想法,这也是克鲁斯卡尔算法的精髓。