• 堆排序,以及大顶堆构造过程Java实现


    1. import java.util.Arrays;
    2. public class Main {
    3. public static void main(String[] args) {
    4. int a[] = new int[] { 1, 1, 23, 456, 0 };
    5. // int a初始化方式
    6. int bb[] = { 1, 2, 3, 4 };
    7. // int c[5] = {1,2,34,5,6};//错误
    8. int d[] = new int[6]; // 初始为0
    9. // int e[] = new int[5]{1,2,34,52,2}; 错误
    10. int f[] = new int[] { 1, 2, 3, 4, 5, 6 };
    11. for (int i = 0; i != 6; ++i) {
    12. System.out.println("ay i=" + d + ",value=" + d[i]);
    13. }
    14. System.out.println("------------");
    15. // Arrays.fill(a, 0, 6, 1);
    16. Arrays.parallelSort(a, 0, 5);
    17. // 快速升序排序
    18. for (int i = 0; i != 5; ++i) {
    19. System.out.println("ay i=" + i + ",value=" + a[i]);
    20. }
    21. int[] b = Arrays.copyOfRange(a, 1, 7);
    22. // Array是copy,是浅copy,from需要小于长度,to超过长度将初始化为0
    23. for (int i = 0; i != 6; ++i) {
    24. System.out.println("by i=" + i + ",value=" + b[i]);
    25. }
    26. int heap_max[] = { 111, 2121, 222, 113, 11111114, 5111, 1, 3, 24, 1, 213, 123 };
    27. // maxHeap(heap_max, 5);
    28. int size = 12;
    29. while (size > 0) {
    30. maxHeap(heap_max, size);
    31. int last = heap_max[size - 1];
    32. heap_max[size - 1] = heap_max[0];
    33. heap_max[0] = last;
    34. size--;
    35. }
    36. }
    37. static void maxHeap(int a[], int size) {
    38. int last_index = size - 1;
    39. // 自下而上检测
    40. while (last_index > 0) {
    41. int root_index = last_index / 2;
    42. if (last_index % 2 == 0) {
    43. root_index = root_index - 1;
    44. } else {
    45. }
    46. int root = a[root_index];
    47. int left = a[root_index * 2 + 1];
    48. int right = 0;
    49. if (root_index * 2 + 2 < size) {
    50. right = a[root_index * 2 + 2];
    51. }
    52. if (root < left) {
    53. if (left < right) {
    54. int rc = root;
    55. a[root_index] = right;
    56. a[root_index * 2 + 2] = rc;
    57. } else {
    58. int rc = root;
    59. a[root_index] = left;
    60. a[root_index * 2 + 1] = rc;
    61. }
    62. } else {
    63. if (root < right) {
    64. int rc = root;
    65. a[root_index] = right;
    66. a[root_index * 2 + 2] = rc;
    67. }
    68. }
    69. last_index -= 2;
    70. // System.out.println(Arrays.toString(a));
    71. }
    72. // 自上而下检测所有根节点
    73. int index = 0;
    74. while (index < size) {
    75. int root_index = index;
    76. int root = a[root_index];
    77. int left_index = root_index * 2 + 1;
    78. int left = 0;
    79. if (left_index < size) {
    80. left = a[left_index];
    81. } else {
    82. left = -1;
    83. break;
    84. }
    85. int right_index = root_index * 2 + 2;
    86. int right = 0;
    87. if (right_index < size) {
    88. right = a[right_index];
    89. } else {
    90. right = -1;
    91. break;
    92. }
    93. if (root < left) {
    94. if (left < right) {
    95. int rc = root;
    96. a[root_index] = a[right_index];
    97. a[right_index] = rc;
    98. } else {
    99. int rc = root;
    100. a[root_index] = a[left_index];
    101. a[left_index] = rc;
    102. }
    103. } else {
    104. if (root < right) {
    105. int rc = root;
    106. a[root_index] = a[right_index];
    107. a[right_index] = rc;
    108. }
    109. }
    110. index++;
    111. // System.out.println(Arrays.toString(a));
    112. }
    113. System.out.println(Arrays.toString(a));
    114. }
    115. }

    先上代码,堆排序一直是稀里糊涂的。找了视频,一看就明白了,自己动手撸了一下。

    一般用数组构建一种堆的关系。在数组中

    每个根节点的下标

    root_index = left_child_index/2

    root_index = right_child_index/2 -1;

     

    left_child_index = 2*root_index+1;

    right_child_index = 2*root_index+2;

     

    记住这个关系,然后按照i堆的构建顺序执行

    1.   构建2叉树,即按照上述位置关系构建

    2.  自下而上检测:

             依次从最后一个节点开始,查找每个节点的根节点,然后根据根节点,继续找出左右子节点,在三个节点中取最大值和根节点交换位置

    3.  自上而下检测

            依次从一个节点开始,查找每个节点的左右子节点,在三个节点中取最大值和根节点交换位置

     

    记住这三条顺序,就行了。

    Tips:

         具体编码建议,在第二步中,如果依次遍历,将会存在大量重复计算节点的操作。因为是从叶节点开始,那么每个节点有两个叶节点,就会找两次,所以每次找完,下标-2就行,直接进入下一个根节点

            第三步中,有可能找不到叶节点,当找不到左右节点时,直接跳出循环就行了,说明已经将所有的根节点找完了。根找完了,就说明调整完毕。

    最后是打印的顺序。

    [11111114, 2121, 5111, 113, 213, 222, 1, 3, 24, 1, 111, 123]
    [5111, 2121, 222, 113, 213, 123, 1, 3, 24, 1, 111, 11111114]
    [2121, 213, 222, 113, 111, 123, 1, 3, 24, 1, 5111, 11111114]
    [222, 213, 123, 113, 111, 1, 1, 3, 24, 2121, 5111, 11111114]
    [213, 113, 123, 24, 111, 1, 1, 3, 222, 2121, 5111, 11111114]
    [123, 113, 3, 24, 111, 1, 1, 213, 222, 2121, 5111, 11111114]
    [113, 111, 3, 24, 1, 1, 123, 213, 222, 2121, 5111, 11111114]
    [111, 24, 3, 1, 1, 113, 123, 213, 222, 2121, 5111, 11111114]
    [24, 1, 3, 1, 111, 113, 123, 213, 222, 2121, 5111, 11111114]
    [3, 1, 1, 24, 111, 113, 123, 213, 222, 2121, 5111, 11111114]
    [1, 1, 3, 24, 111, 113, 123, 213, 222, 2121, 5111, 11111114]
    [1, 1, 3, 24, 111, 113, 123, 213, 222, 2121, 5111, 11111114]

    堆排序的过程。

    第一步:
        每次用数组中的[0,N)个元素构建堆。构建结束后,最大的数位于0下标位置。

    第二步:将0下标和数组中最后一个元素交换位置。交换后,最大的数位于最后一个位置上

    第三步:N=N-1 ,重复第一步,N=1跳出循环就行了

    总结:

    还是用java刷题爽,用C++没那么方便。后面干到200题去面MS

     

     

  • 相关阅读:
    【华为OD机试python】返回矩阵中非1的元素个数【2023 B卷|200分】
    基于python+Django的二维码生成算法设计与实现
    为什么 NGINX 的 reload 命令不是热加载?
    JS中的链
    gitlab runner 不清理云端已经删除的tag和branch问题记录
    Leetcode 792. 匹配子序列的单词数
    go 字符串操作
    PAT 1122 Hamiltonian Cycle
    基于SpringBoot的企业部门与员工管理系统,毕设、课设资源包,附送项目源码和数据库脚本
    Java Excel转PDF,支持xlsx和xls两种格式, itextpdf【即取即用】
  • 原文地址:https://blog.csdn.net/zanglengyu/article/details/132735378