利用最大(最小)堆进行处理的一种排序方法
将整个数组看做一个完全二叉树(按层级从左到右依次构成一颗树)其具有以下公式:
对于第k个元素 他的父节点为 (k - 1) / 2, 他的左子节点 2k + 1, 右子节点 2k + 2
算法流程:
1、将整个树形结构 “调整” 为“大(小)根堆”, 所谓 “大(小)根堆” 就是其顶部节点比左右子子结点都大(小)
2、将前 n 个节点的最后一个节点与第一个节点交换,对前 n - 1个元素继续调整。 将前 n-1 个重复前面操作, … 直到 n 为 1
代码
**
/**** @param {Array} nums* @param {Number} n 前n个元素进行调整* @param {Number} k 第k个元素开始调整*/function adjust(nums, n, k){let left = 2 * k + 1, right = 2 * k + 2, max = kif(left < n && nums[max] < nums[left]) max = leftif(right < n && nums[max] < nums[right]) max = rightif(max != k) {swap(nums, max, k)adjust(nums, n, max)}}function HeapSort(nums){/*** 第一步,将整个节点调整为大根堆* 对于一个树来说将其调整为大根堆,我们只需要从最后一个 ”叶子节点的父节点“(n - 1) / 2 这个节点开始逆序依次调整*/for (let k = (nums.length - 1) / 2 | 0; k >= 0; k--) {adjust(nums, nums.length, k)}/*** 第二步,将第一个元素与第 n 到 1 个 依次交换,调整*/for (let k = nums.length - 1; k > 0; k--) {swap(nums, 0 , k)adjust(nums, k, 0)}return nums}
时间复杂度O(nlog(n))
空间复杂度O(1)
