这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战
上一篇文章学习了排序方法, 另更多更文学习 JavaScript 的系列小总结更多阅读 & 经典排序算法
本文来继续学习经典排序方法: 堆排序 Heapsort
JS实现排序算法-堆排序 Heapsort
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构, 并同时满足堆积的性质: 即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。 堆排序的平均时间复杂度为 Ο(nlogn)。
堆排序分为两种方法:
大顶堆: 每个节点的值都大于或等于其子节点的值, 在堆排序算法中用于升序排列;小顶堆: 每个节点的值都小于或等于其子节点的值, 在堆排序算法中用于降序排列;
堆排序 算法步骤
- 将待排序序列构建成一个堆
H[0……n-1],根据(升序降序需求)选择大顶堆或小顶堆; - 把堆首(最大值)和堆尾互换;
- 把堆的尺寸缩小 1,并调用
shift_down(0),目的是把新的数组顶端数据调整到相应位置; - 重复步骤 2,直到堆的尺寸为 1。
堆排序 JS 代码实现:
- 功能函数封装
var len // 因为声明的多个函数都需要数据长度,所以把len设置成为全局变量
function buildMaxHeap(arr) {
// 建立大顶堆
len = arr.length
for (var i = Math.floor(len / 2); i >= 0; i--) {
heapify(arr, i)
}
}
function heapify(arr, i) {
// 堆调整
var left = 2 * i + 1,
right = 2 * i + 2,
largest = i
if (left < len && arr[left] > arr[largest]) {
largest = left
}
if (right < len && arr[right] > arr[largest]) {
largest = right
}
if (largest != i) {
swap(arr, i, largest)
heapify(arr, largest)
}
}
function swap(arr, i, j) {
var temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
- 排序算法
heapSort()函数实现
function heapSort(arr) {
buildMaxHeap(arr)
for (var i = arr.length - 1; i > 0; i--) {
swap(arr, 0, i)
len--
heapify(arr, 0)
}
return arr
}
// 引入下面的 测试代码耗时的方法: 进行测试希尔排序对处理20000+条数据的排序耗时:
getFnRunTime(heapSort)
代码运行耗时方法
const testArrFn = function () {
let arr = []
const count = 200000
for (let i = 0; i < count; i++) {
arr[i] = Math.floor(Math.random() * 50 + 1)
}
return arr
}
let testArr = testArrFn()
let len = testArr.length
/**
* @desc 测试函数执行的时间
*/
module.exports = async function getFnRunTime(fn) {
let startTime = Date.now(),
endTime
let result = await fn(testArr)
endTime = Date.now()
console.log(testArr, result)
console.log(`total time: ${endTime - startTime}ms, `, "test array'length: " + len, result.length)
}
更多阅读
- 【Array.prototype.map() 】、
- 【JS-特殊符号-位运算符】、
- 【ES6 - for/of】、
- 【JS-逻辑运算符-短路了?】、
- 【JS-箭头函数】、
- 【JavaScript-forEach()】、