前言
这里以递归为例,参考自慕课网刘波波老师的C++版本实现
普通堆排序(实现了一个完整的堆)
普通的堆排序首先肯定要有堆,这里我实现了一个最大堆,它必须要有insert方法shiftUp方法和来向堆插入新元素,用extractMax和shiftDown方法对堆出元素。
function MaxHeap(arr, capacity) {
var data = new Array([capacity + 1]),
count = 0;
arr.forEach(function(item, index) {
data[index + 1] = item;
});
count = arr.length;
for (var i = ~~(count / 2); i >= 1; i--) {
shiftDown(i);
}
function shiftUp(k) {
var middle = ~~(k / 2);
//左子节点小于父节点
while (k > 1 && data[middle] < data[k]) {
//交换左子节点和父节点
[data[middle], data[k]] = [data[k], data[middle]];
k = middle;
middle = ~~(k / 2);
}
}
function shiftDown(k) {
//没越界
while (2 * k <= count) {
//j先是左孩子,如果右孩子大就变成了右孩子
var j = 2 * k; // 在此轮循环中,data[k]和data[j]交换位置
if (j + 1 <= count && data[j + 1] > data[j])
j++;
// data[j] 是 data[2*k]和data[2*k+1]中的最大值
if (data[k] >= data[j]) break;
[data[k], data[j]] = [data[j], data[k]];
k = j;
}
}
function size() {
return count;
}
function isEmpty() {
return count == 0;
}
function insert(item) {
data[count + 1] = item;
shiftUp(count + 1);
count++;
}
function extractMax() {
var ret = data[1];
[data[1], data[count]] = [data[count], data[1]];
// data.pop();
count--;
shiftDown(1);
return ret;
}
function getMax() {
return data[1];
}
return {
data: data,
size: size,
isEmpty: isEmpty,
insert: insert,
extractMax: extractMax,
getMax: getMax
}
}
var heapSort = function(arr) {
var len = arr.length;
var heap = new MaxHeap(arr,len);
for (var i = len - 1; i >= 0; i--) {
arr[i] = heap.extractMax();
}
return arr;
}
优化堆排序(只借用了堆的)
堆排序主要就是使用了最大(小)堆的性质:根节点是最大(小)值,一直让根节点出堆就行了,明白了这点,我们只需要堆结构的shiftdown方法即可。
var heapSort = function(arr) {
var len = arr.length;
//heapify
for (var i = ~~((len - 1) / 2); i >= 0; i--) {
shiftdown(arr, len, i);
}
for (var i = len - 1; i > 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]];
shiftdown(arr, i, 0);
}
return arr;
}
function shiftdown(arr, length, k) {
while (2 * k + 2 <= length) {
//j先是左孩子,如果右孩子大就变成了右孩子
var j = 2 * k + 1; // 在此轮循环中,arr[k]和arr[j]交换位置
if (j + 1 < length && arr[j + 1] > arr[j])
j++;
// arr[j] 是 arr[2*k]和arr[2*k+1]中的最大值
if (arr[k] >= arr[j]) break;
[arr[k], arr[j]] = [arr[j], arr[k]];
k = j;
}
}