• 详细堆排序的实现


    目录

    建堆有两种方法(以升序为例):

    建完堆之后,就可以去排序了:

    以下是向上调整和向下调整的两个接口:

    完整实现和测试代码:

    首先,排序之前要先建立一个堆来实现排序

    由于兄弟之间无大小关系,所以:

            实现升序要创建大堆

            实现降序要创建小堆

    建堆有两种方法(以升序为例):

    1.利用AdjustUp(向上调整):

    从第二个数据(因为第一个数据上面无父节点),也就是下标为1的那个点开始遍历调整数据,只要该节点上面的父节点比该点小,就互换数据(Swap),最后就会建立出一个大堆。

    1. // 建大堆
    2. // O(N*logN)
    3. for (int i = 1; i < n; i++)
    4. {
    5. AdjustUp(a, i);
    6. }

    2.利用AdjustDown(向下调整):

    从倒数第一个非叶子节点,也就是倒数第一个父节点开始(建成分成许多个分散的大堆),只要该节点上面的父节点比该点小,就互换数据(Swap),最后就会建立出一个大堆。

    1. // O(N)
    2. for (int i = (n - 1 - 1) / 2; i >= 0; --i)
    3. {
    4. AdjustDown(a, n, i);
    5. }

    这两种方法中,更推荐下面这种,因为时间复杂度稍低,而且下方排序也要用到向下调整接口,这样就节省了一个接口。

    建完堆之后,就可以去排序了:

    通过大堆的顶端元素最大的特性,可以将尾数据和top数据交换(Swap),AdjustDown的参数中传进去的end是个判断点,size--后,就可以将top那个最大的数据保存在尾部,然后利用向上调整的特性,次大的数据又到了top点,再次交换,size--,依次进行下去,最后就将最大,次大,次次大......依次放到了尾部,就排序完成了。

    1. //0(N*logN)
    2. int end = n - 1;
    3. while (end > 0)
    4. {
    5. Swap(&a[0], &a[end]);
    6. AdjustDown(a, end, 0);
    7. end--;
    8. }

    以下是向上调整和向下调整的两个接口:

    1. void AdjustUp(HPDataType* a, int child)
    2. {
    3. int parent = (child - 1) / 2;
    4. while (child > 0)
    5. {
    6. if (a[child] < a[parent])
    7. {
    8. Swap(&a[child], &a[parent]);
    9. child = parent;
    10. parent = (child - 1) / 2;
    11. }
    12. else
    13. {
    14. break;
    15. }
    16. }
    17. }
    18. void AdjustDown(int* a, int size, int parent)
    19. {
    20. int child = parent * 2 + 1;
    21. while (child < size)
    22. {
    23. // 假设左孩子大
    24. if (child + 1 < size && a[child + 1] > a[child])
    25. {
    26. ++child;
    27. }
    28. if (a[child] > a[parent])
    29. {
    30. Swap(&a[child], &a[parent]);
    31. parent = child;
    32. child = parent * 2 + 1;
    33. }
    34. else
    35. {
    36. break;
    37. }
    38. }
    39. }

    完整实现和测试代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. typedef int HPDataType;
    7. void Swap(HPDataType* p1, HPDataType* p2)
    8. {
    9. HPDataType tmp = *p1;
    10. *p1 = *p2;
    11. *p2 = tmp;
    12. }
    13. void AdjustUp(HPDataType* a, int child)
    14. {
    15. int parent = (child - 1) / 2;
    16. while (child > 0)
    17. {
    18. if (a[child] < a[parent])
    19. {
    20. Swap(&a[child], &a[parent]);
    21. child = parent;
    22. parent = (child - 1) / 2;
    23. }
    24. else
    25. {
    26. break;
    27. }
    28. }
    29. }
    30. void AdjustDown(int* a, int size, int parent)
    31. {
    32. int child = parent * 2 + 1;
    33. while (child < size)
    34. {
    35. // 假设左孩子大
    36. if (child + 1 < size && a[child + 1] > a[child])
    37. {
    38. ++child;
    39. }
    40. if (a[child] > a[parent])
    41. {
    42. Swap(&a[child], &a[parent]);
    43. parent = child;
    44. child = parent * 2 + 1;
    45. }
    46. else
    47. {
    48. break;
    49. }
    50. }
    51. }
    52. // 升序
    53. void HeapSort(int* a, int n)
    54. {
    55. // 建大堆
    56. // O(N*logN)
    57. /*for (int i = 1; i < n; i++)
    58. {
    59. AdjustUp(a, i);
    60. }*/
    61. // O(N)
    62. for (int i = (n - 1 - 1) / 2; i >= 0; --i)
    63. {
    64. AdjustDown(a, n, i);
    65. }
    66. //0(N*logN)
    67. int end = n - 1;
    68. while (end > 0)
    69. {
    70. Swap(&a[0], &a[end]);
    71. AdjustDown(a, end, 0);
    72. end--;
    73. }
    74. }
    75. int main()
    76. {
    77. int a[] = { 4, 6, 2, 1, 5, 8, 2, 9 };
    78. HeapSort(a, sizeof(a)/sizeof(int));
    79. for (int i = 0; i < sizeof(a)/sizeof(int); i++)
    80. {
    81. printf("%d ", a[i]);
    82. }
    83. printf("\n");
    84. return 0;
    85. }
  • 相关阅读:
    9.7黄金是否会继续下跌?后市如何布局
    Redis系列4:高可用之Sentinel(哨兵模式)
    C语言 二叉树
    云原生|kubernetes|本地存储hostpath-provisioner部署以及无token密码方式登陆dashboard的部署
    html计算器
    springMvc24-Eclipse设置代码自动提示
    成为Linux大神——必须要具备的基本技能!
    MQTT vs. XMPP,哪一个才是IoT通讯协议的正解
    01目标检测-问题引入
    07 nginx 的 worker process 的调试
  • 原文地址:https://blog.csdn.net/cy18779588218/article/details/134655564