1. package sort;
    2. import java.util.Arrays;
    3. import java.util.stream.Collectors;
    4. public class HeapSort {
    5. /**
    6. * 选择排序-堆排序-不稳定排序
    7. * @param array 待排序数组
    8. * @return 已排序数组
    9. */
    10. public static int[] heapSort(int[] array){
    11. //这里元素的索引是从0开始的,所以最后一个非叶子结点array.length/2 - 1
    12. for(int i= array.length/2-1; i>=0; i--){
    13. adjustHeap(array, i, array.length); // 调整堆
    14. }
    15. // 上述逻辑,建堆结束
    16. // 下面,开始排序逻辑
    17. for(int j = array.length-1; j>0; j--){
    18. // 元素交换,作用是去掉大顶堆
    19. // 把大顶堆的根元素,放到数组的最后;
    20. // 换句话说,就是每一次的堆调整之后,都会有一个元素到达自己的最终位置
    21. swap(array, 0, j);
    22. adjustHeap(array, 0, j);
    23. }
    24. return array;
    25. }
    26. /**
    27. * 整个堆排序最关键的地方
    28. * @param array 待组堆
    29. * @param i 起始结点
    30. * @param length 堆的长度
    31. */
    32. public static void adjustHeap(int[] array, int i, int length){
    33. // 先把当前元素取出来,因为当前元素可能要一直移动
    34. int temp = array[i];
    35. // 2*i+1 为i的左子树
    36. // 2*k+1 为k的左子树
    37. for(int k = 2 * i + 1; k < length; k = 2 * k + 1){
    38. // 让 k 先指向子节点中最大的节点
    39. if(k+1 < length && array[k] < array[k+1]){ // 如果有右子树,并且右子树大于左子树
    40. k++;
    41. }
    42. // 如果发现节点(左右子节点)大于根节点,则进行值的交换
    43. if(array[k] > temp){
    44. swap(array, i, k);
    45. i = k;
    46. } else {
    47. break;
    48. }
    49. }
    50. }
    51. public static void swap(int[] arr, int a, int b){
    52. int temp = arr[a];
    53. arr[a] = arr[b];
    54. arr[b] = temp;
    55. }
    56. public static void main(String[] args) {
    57. int []arr = {9,8,7,6,5,4,3,2,1};
    58. arr = heapSort(arr);
    59. System.out.println(Arrays.stream(arr).boxed().collect(Collectors.toList()));
    60. }
    61. }