• 堆排序--C语言版


    一.堆排序

    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
    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)是其父亲的节点,也就是最后一个非叶子节点的下标。

  • 相关阅读:
    231n--神经网络和反向传播
    计算机微信小程序毕业设计题目SSM项目小说阅读器+后台管理系统|前后分离VUE[包运行成功]
    C++覆盖和保护成员
    2021最新中高级Java面试题目,Java面试题汇总
    药物临床试验数据递交PMDA的规定
    Three.js入门详解
    二进制安装minio 并实现主从同步
    LeetCode-404. Sum of Left Leaves [C++][Java]
    FPGA——用VGA时序显示图像(3)(代码)
    HALCON reference_hdevelop翻译Chapter1 1D Measuring(二)
  • 原文地址:https://blog.csdn.net/anyway33/article/details/126524993