上一篇博客已经学习了堆以及堆排序的思想,不了解堆的可以先学习这篇博客。
直接上JS实现堆以及堆排序:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>堆排序</title>
</head>
<body>
<script>
//注意:数组下标是0~length-1
//堆调整的范围由start~end
function heapAdjust(arr, start, end) {
let heapTop = arr[start] //该元素将插入arr[start+1] ~ arr[end]的堆中,由于arr[start]还不确定插入哪里,所以先用变量保存
let i
for (i = 2 * start + 1; i <= end; i = 2 * i + 1) {
if (i + 1 <= end && arr[i] < arr[i + 1]) i = i + 1 //i+1<=length是为了确保arr[i+1]取值时,下标不越界,越界就会报错
if (heapTop > arr[i]) break
arr[start] = arr[i] //heapTop比子结点小,子节点往上移
start = i //注意:start一直更新着heapTop应该插入位置的下标
}
arr[start] = heapTop //来到这里说明heapTop应该插入这里
}
function createHeap(arr) {
let n = Math.floor(length / 2)
for (let i = n - 1; i >= 0; i--) {
//将arr[n-1]...arr[0]逐一进入堆中
heapAdjust(arr, i, length - 1)
}
}
function heapSort() {
createHeap(arr)
for (let i = length - 1; i > 0; i = i - 1) {
//进行length-1次将堆顶元素与未排序的序列最后一个元素进行交换,再进行堆调整,最终得到排序序列
let temp = arr[0]
arr[0] = arr[i]
arr[i] = temp
heapAdjust(arr, 0, i - 1) //第i位元素时已经排好序的元素,堆调整时不用再调整i-1后面的元素位置
}
console.log(arr)
}
var arr = [49, 38, 65, 97, 76, 13, 27, 49, 75, 165, -5]
var length = arr.length
heapSort()
</script>
</body>
</html>
结果: