当前位置:   article > 正文

最小生成树---Kruskal_小根堆只保证最顶端

小根堆只保证最顶端




2. Kruskal

将边按权值从小到大排列【取出之后不再需要处理,所以可以考虑用最小堆进行排序】
然后 按照权值递增的顺序查看每一条边:
假如第k条边(v, w), 如果两个端点 v 和 w 分别在当前两个不同的连通分支中, 就用变 边(v, w)将 两个连通分支连接起来
否则 直接处理下一条边

++++++++++++++++++++++++++++
PS:
1. 这个需要用到 小根堆。 关于小根堆,只是堆排序中的一个步骤。它只保证最顶端的是最小的元素。当取走这个元素之后,重新进行一次堆调整,然后,堆顶元素又是最小的了。
2. 建小根堆的时候要特别注意, 

int start = heapsize / 2 - 1;  

for (; start >= 0; start--)  
small_root_heapify(heap, start, heapsize );  

个数,起始点编号和是否取到编号0这个问题

3.  关于Kruskal里面,判断两个端点v和w是否在不同的连通分支中。 
所以这个需要给每个端点打标记。最开始用的 o or 1,认为加入和不加入两种情况,可是这样,所有的点开始都是0, v != w时才可以加入,所以没有可加入点了==
后来,给每个点打标记为自身编号,每个加入的边,后一个点的标记 记为 前一个点的标记。同时,需要判断加入的边的条数k, 用来防止生成了闭环。
++++++++++++++++++++++++++++


  1. / alg_for_test.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <float.h> //FLT_MAX
  5. #include <stdlib.h>
  6. #define NUMOFDOT 6 //点的个数
  7. //定义一条边,两个点及其边的权值
  8. typedef struct node
  9. {
  10. int node1;
  11. int node2;
  12. float weight;
  13. }EdgeNode;
  14. void createMinHeap(EdgeNode *heap, int heapSize) ;
  15. EdgeNode removeMin(EdgeNode *heap, int heapSize) ;
  16. void small_root_heapify(EdgeNode *heap, int i, int heapSize) ;
  17. void printHeap(EdgeNode heap[],int HeapSize);
  18. void kruskal(EdgeNode myEdgeNode[] );
  19. int main()
  20. {
  21. float c[NUMOFDOT][NUMOFDOT] = {
  22. FLT_MAX, 6, 1, 5, FLT_MAX, FLT_MAX,
  23. 6, FLT_MAX, 5, FLT_MAX, 3, FLT_MAX,
  24. 1, 5, FLT_MAX, 5, 6, 4,
  25. 5, FLT_MAX, 5, FLT_MAX, FLT_MAX, 2,
  26. FLT_MAX, 3, 6, FLT_MAX, FLT_MAX, 6,
  27. FLT_MAX, FLT_MAX, 4, 2, 6, FLT_MAX
  28. };
  29. EdgeNode myEdgeNode[NUMOFDOT * NUMOFDOT];
  30. int cnt = 0;
  31. for(int i = 0; i < NUMOFDOT; i++)
  32. {
  33. for(int j = 0; j < NUMOFDOT; j++)
  34. {
  35. myEdgeNode[cnt].node1 = i;
  36. myEdgeNode[cnt].node2 = j;
  37. myEdgeNode[cnt].weight = c[i][j];
  38. cnt++;
  39. }
  40. }
  41. kruskal(myEdgeNode);
  42. system("pause");
  43. return 0;
  44. }
  45. void kruskal(EdgeNode myEdgeNode[] )
  46. {
  47. int e = NUMOFDOT * NUMOFDOT;
  48. int flag[NUMOFDOT] = {0, 1, 2, 3, 4, 5 };// 打标机,0表示未加入 "团"
  49. //printHeap(myEdgeNode, e);
  50. createMinHeap(myEdgeNode, e);
  51. //printHeap(myEdgeNode, e);
  52. int k = 0; //用来记录已经加入的点的个数
  53. while(e > 0 && k < NUMOFDOT - 1)
  54. {
  55. EdgeNode x = (EdgeNode) removeMin(myEdgeNode, e); //从堆中去出权值最小的一条边
  56. //for test
  57. //printf("e = %d\t, %d, %d, %f \n", e, x.node1, x.node2, x.weight);
  58. int a = flag[x.node1];
  59. int b = flag[x.node2];
  60. //如果取出的这一条边的两个端点不在一个联通域中,这条边可连接起来
  61. if(a != b )
  62. {
  63. printf("edges %d --- %d added\n", x.node1, x.node2);
  64. //将这两点连接起来,ab属于一个连通域了。。
  65. flag[x.node2] = flag[x.node1];
  66. k++;
  67. }
  68. e--; //边数-1
  69. }
  70. }
  71. void printHeap(EdgeNode heap[],int HeapSize)
  72. {
  73. for(int i = 0;i < HeapSize; ++i)
  74. {
  75. printf("heap's node1 = %d, node2 = %d, weight = %f\n", heap[i].node1, heap[i].node2, heap[i].weight);
  76. }
  77. }
  78. void createMinHeap(EdgeNode *heap, int heapsize)
  79. {
  80. int start = heapsize / 2 - 1;
  81. for (; start >= 0; start--)
  82. small_root_heapify(heap, start, heapsize );
  83. }
  84. void small_root_heapify(EdgeNode *heap, int i, int heapsize)
  85. {
  86. int l = 2 * i + 1;
  87. int r = 2 * i + 2;
  88. int smallest;
  89. EdgeNode temp;
  90. if (l < heapsize && heap[l].weight < heap[i].weight)
  91. smallest = l;
  92. else
  93. smallest = i;
  94. if (r < heapsize && heap[r].weight < heap[smallest].weight)
  95. smallest = r;
  96. if (i != smallest)
  97. {
  98. temp = heap[i];
  99. heap[i] = heap[smallest];
  100. heap[smallest] = temp;
  101. small_root_heapify(heap, smallest, heapsize) ;
  102. }
  103. }
  104. EdgeNode removeMin(EdgeNode *heap, int heapsize)
  105. {
  106. EdgeNode min;
  107. if (heapsize < 1)
  108. printf("***heap underflow***");
  109. min = heap[0];
  110. heap[0] = heap[heapsize-1];
  111. heapsize--;
  112. small_root_heapify(heap, 0, heapsize);
  113. return min;
  114. }












以上随便写着玩的,

认真请看《算法设计与分析》


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/243425
推荐阅读
相关标签
  

闽ICP备14008679号