【java面试】算法篇之堆排序

 

一、堆的概念

堆是一棵顺序存储的完全二叉树。完全二叉树中所有非终端节点的值均不大于(或不小于)其左、右孩子节点的值。

其中每个节点的值小于等于其左、右孩子的值,这样的堆称为小根堆;

其中每个节点的值大于等于其左、右孩子的值,这样的堆称为大根堆;

二、要点

1.将数组构造成初始堆(若想升序则建立大根堆,若想降序,则建立小根堆)

从最后一个节点开始调整,得到初始堆。

2.堆排序处理

交换堆顶的元素和最后一个元素,此时最后一个位置作为有序区(有序区显示为黄色),然后进行其他无序区的堆调整,重新得到大顶堆后,交换堆顶和倒数第二个元素的位置……

重复此过程:

最后,有序扩展完成即排序完成:

核心代码

 
  1. public void HeapAdjust(int[] array, int parent, int length) {

  2.  
  3. int temp = array[parent]; // temp保存当前父节点

  4.  
  5. int child = 2 * parent + 1; // 先获得左孩子

  6.  
  7.  
  8.  
  9. while (child < length) {

  10.  
  11. // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点

  12.  
  13. if (child + 1 < length && array[child] < array[child + 1]) {

  14.  
  15. child++;

  16.  
  17. }

  18.  
  19.  
  20.  
  21. // 如果父结点的值已经大于孩子结点的值,则直接结束

  22.  
  23. if (temp >= array[child])

  24.  
  25. break;

  26.  
  27.  
  28.  
  29. // 把孩子结点的值赋给父结点

  30.  
  31. array[parent] = array[child];

  32.  
  33.  
  34.  
  35. // 选取孩子结点的左孩子结点,继续向下筛选

  36.  
  37. parent = child;

  38.  
  39. child = 2 * child + 1;

  40.  
  41. }

  42.  
  43.  
  44.  
  45. array[parent] = temp;

  46.  
  47. }

  48.  
  49.  
  50.  
  51. public void heapSort(int[] list) {

  52.  
  53. // 循环建立初始堆

  54.  
  55. for (int i = list.length / 2; i >= 0; i--) {

  56.  
  57. HeapAdjust(list, i, list.length - 1);

  58.  
  59. }

  60.  
  61.  
  62.  
  63. // 进行n-1次循环,完成排序

  64.  
  65. for (int i = list.length - 1; i > 0; i--) {

  66.  
  67. // 最后一个元素和第一元素进行交换

  68.  
  69. int temp = list[i];

  70.  
  71. list[i] = list[0];

  72.  
  73. list[0] = temp;

  74.  
  75.  
  76.  
  77. // 筛选 R[0] 结点,得到i-1个结点的堆

  78.  
  79. HeapAdjust(list, 0, i);

  80.  
  81. System.out.format("第 %d 趟: \t", list.length - i);

  82.  
  83. printPart(list, 0, list.length - 1);

  84.  
  85. }

  86.  
  87. }

猜你喜欢

转载自blog.csdn.net/It_BeeCoder/article/details/82386472