利用最大(最小)堆进行处理的一种排序方法
    将整个数组看做一个完全二叉树(按层级从左到右依次构成一颗树)其具有以下公式:
    对于第k个元素 他的父节点为 (k - 1) / 2, 他的左子节点 2k + 1, 右子节点 2k + 2

    算法流程:
    1、将整个树形结构 “调整” 为“大(小)根堆”, 所谓 “大(小)根堆” 就是其顶部节点比左右子子结点都大(小)
    2、将前 n 个节点的最后一个节点与第一个节点交换,对前 n - 1个元素继续调整。 将前 n-1 个重复前面操作, … 直到 n 为 1

    代码
    **

    1. /**
    2. *
    3. * @param {Array} nums
    4. * @param {Number} n 前n个元素进行调整
    5. * @param {Number} k 第k个元素开始调整
    6. */
    7. function adjust(nums, n, k){
    8. let left = 2 * k + 1, right = 2 * k + 2, max = k
    9. if(left < n && nums[max] < nums[left]) max = left
    10. if(right < n && nums[max] < nums[right]) max = right
    11. if(max != k) {
    12. swap(nums, max, k)
    13. adjust(nums, n, max)
    14. }
    15. }
    16. function HeapSort(nums){
    17. /**
    18. * 第一步,将整个节点调整为大根堆
    19. * 对于一个树来说将其调整为大根堆,我们只需要从最后一个 ”叶子节点的父节点“(n - 1) / 2 这个节点开始逆序依次调整
    20. */
    21. for (let k = (nums.length - 1) / 2 | 0; k >= 0; k--) {
    22. adjust(nums, nums.length, k)
    23. }
    24. /**
    25. * 第二步,将第一个元素与第 n 到 1 个 依次交换,调整
    26. */
    27. for (let k = nums.length - 1; k > 0; k--) {
    28. swap(nums, 0 , k)
    29. adjust(nums, k, 0)
    30. }
    31. return nums
    32. }

    时间复杂度O(nlog(n))
    空间复杂度O(1)