当前位置:   article > 正文

堆排序--HeapSort()_使用堆排序算法实现升序排序,并把每趟排序结果输出

使用堆排序算法实现升序排序,并把每趟排序结果输出

一.堆排序

1.首先区别于升序打印或者降序打印

(1)升序打印:

  1. void TestHeapSort()
  2. {
  3. // 升序打印 -- 小堆
  4. // 降序打印 -- 大堆
  5. HP hp;
  6. HeapInit(&hp);
  7. int a[] = { 27, 15, 19, 18, 28, 34, 65, 49, 25, 37 };
  8. for (int i = 0; i < sizeof(a) / sizeof(int); ++i)
  9. {
  10. HeapPush(&hp, a[i]);
  11. }
  12. while (!HeapEmpty(&hp))
  13. {
  14. printf("%d ", HeapTop(&hp));
  15. HeapPop(&hp);
  16. }
  17. printf("\n");
  18. int a[] = { 27, 15, 19, 18, 28, 34, 65, 49, 25, 37 };
  19. HeapSort(a, sizeof(a) / sizeof(int));
  20. }

(2)排序

         升序排序--建大堆(父节点值大于子节点)

         降序排序--建小堆(父节点值小于子节点)

         

2.堆排序初级版本(不建议使用版本):

  1. //不好/错误方式:
  2. HP hp;//定义个堆类型的结构体
  3. HeapInit(&hp);
  4. for(int i=0;i<n;i++)
  5. {
  6. HeapPush(&hp,a[i]);
  7. }
  8. int i=0;
  9. while(!HeapEmpty(&hp))
  10. {
  11. a[i]=HeapTop(&hp);
  12. HeapPop(&hp);
  13. }

存在问题:

                  1.内存泄露(小问题)-->添加HeapDestroy

                  2.要先写一个Hp数据结构,复杂

                  3.有O(N)空间复杂度

3.优化版本(正确版本):

整体思路:

#堆排序

 一、建堆(由数组建堆)(堆排序的前提是有堆)

思路:方式1.直接将 已给的数组的每个元素都 进行向上排序    (没有条件限制)

          方式2.向下排序          (parent的左右两边都必须是堆)

二、堆排序

思路:## 升序--大堆--将堆顶最大的元素和最后一个元素交换,放在最后一位,然后size--,每完成一次,堆剩下的数进行一次向下调整,和HeapPop的思路类似。依次将最后一位放最大,倒数第二位放次大,.......依次类推,可以堆进行排序。

(升序--而不是建小堆,因为选出最小放在首位的容易,但选出次小的放在第二位难,之后的都不容易放。只能选一个次小的,再建堆,选次小,建堆,时间复杂度会达到O(N^2),该方法不是不可以,而是效率太差,没有使用到堆的优势  )

  1. //简洁版本
  2. void Swap(int* p1, int* p2)
  3. {
  4. int tmp = *p1;
  5. *p1 = *p2;
  6. *p2 = tmp;
  7. }
  8. voidAdjustUp(HPDataType*a,intchild)
  9. {
  10. intparent=(child-1)/2;
  11. //while (parent >= 0)
  12. while(child>0)
  13. {
  14. //if (a[child] < a[parent])
  15. if(a[child]>a[parent])
  16. {
  17. Swap(&a[child],&a[parent]);
  18. child=parent;
  19. parent=(child-1)/2;
  20. }
  21. else
  22. {
  23. break;
  24. }
  25. }
  26. }
  27. void AdjustDwon(int* a, int size, int parent)
  28. {
  29. int child = parent * 2 + 1;
  30. while (child < size)
  31. {
  32. if (child + 1 < size && a[child + 1] > a[child])
  33. {
  34. ++child;
  35. }
  36. if (a[child] > a[parent])
  37. {
  38. Swap(&a[child], &a[parent]);
  39. parent = child;
  40. child = parent * 2 + 1;
  41. }
  42. else
  43. {
  44. break;
  45. }
  46. }
  47. }
  48. // 降序 -- 建小堆
  49. // 升序 -- 建大堆
  50. void HeapSort(int* a, int n)
  51. {
  52. // 建堆方式1:O(N*logN)
  53. for (int i = 1; i < n; ++i)
  54. {
  55. AdjustUp(a, i);//向上排序
  56. }
  57. // 建堆方式2:O(N)
  58. for (int i = (n - 1 - 1) / 2; i >= 0; --i)
  59. {
  60. AdjustDwon(a, n, i);//向下排序
  61. }
  62. // O(N*logN)
  63. int end = n - 1;
  64. while (end > 0)
  65. {
  66. Swap(&a[0], &a[end]);
  67. AdjustDwon(a, end, 0);
  68. --end;
  69. }
  70. }

 

ps: 以上: int i=(n-1-1)/2解析: n-1是最后一个节点的下标,((n-1)-1)是其父亲的节点,也就是最后一个非叶子节点的下标。

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

闽ICP备14008679号