prefix knowlege: heap
题目: 给定数组 [5, 2, 7, 3, 1, 8, 4]
, 使用堆排序对其进行升序排列。
5↙ ↘ convert2 7|因为子节点 7 大于 5, 因此作 convert, 结果如下↓7↙ ↘2 5|依此类推, 构造出大顶堆。↓8↙ ↘3 7↙ ↘ ↙ ↘2 1 5 4
8↙ ↘3 7↙ ↘ ↙ ↘2 1 5 4|取出顶部 8, 将数组末尾元素 4 移到顶部↓4↙ ↘ (对调)3 7↙ ↘ ↙2 1 5|如果存在顶部元素的子元素大于顶部元素的情形, 对调它们, 重新构造 max heap.↓7↙ ↘3 4↙ ↘ ↙2 1 5|重复上述 3 个步骤, 直到堆中的元素为空
下面来实现上述步骤:
var heap_sort = function(arr) {const result = []let material = arrwhile (material.length > 0) {const maxHeapArr = builtMaxHeap(material)result.unshift(maxHeapArr[0])maxHeapArr[0] = maxHeapArr[maxHeapArr.length - 1]material = maxHeapArr.slice(0, maxHeapArr.length - 1)}return result}// input: [5, 2, 7, 3, 1, 8, 4]// output: to build big heap [8, 3, 7, 2, 1, 5, 4]var builtMaxHeap = function(arr) {let parent, compareChildfor (let i = 0; i < arr.length; i++) {parent = Math.floor((i - 1) / 2)compareChild = iwhile (parent >= 0) {if (arr[parent] < arr[compareChild]) {swap(arr, parent, compareChild)compareChild = parentparent = Math.floor((compareChild - 1) / 2)} else {parent = -1}}}return arr}// swap two value in arrvar swap = function(arr, pointOne, pointTwo) {const tmp = arr[pointOne]arr[pointOne] = arr[pointTwo]arr[pointTwo] = tmp}
理想情况下, 堆排序时间复杂度应为 nlogn, 空间复杂度应为 1, 上述实现的代码中没有达到这一复杂度的。参考社区代码后重写:
var lenvar heap_sort = function(arr) {buildMaxHeapify(arr)while (len > 1) {swap(arr, len - 1, 0)len--keepMaxHeapify(arr, 0)}return arr}/*** to build max heapify from bottom to top;* the last subscript's parent subscript is Math.floor((len - 1) / 2)*/var buildMaxHeapify = function(arr) {len = arr.lengthfor (let i = Math.floor((len - 1) / 2); i >= 0; i--) {keepMaxHeapify(arr, i)}}/*** to keep max heap*/var keepMaxHeapify = function(arr, i) {const left = 2 * i + 1const right = 2 * i + 2let maxSubscript = iif (left < len && arr[left] > arr[maxSubscript]) {maxSubscript = left}if (right < len && arr[right] > arr[maxSubscript]) {maxSubscript = right}if (maxSubscript !== i) {swap(arr, maxSubscript, i)keepMaxHeapify(arr, maxSubscript)}}/*** swap two value in arr*/var swap = function(arr, pointOne, pointTwo) {const tmp = arr[pointOne]arr[pointOne] = arr[pointTwo]arr[pointTwo] = tmp}