JavaScript中的堆[heap]数据结构
2023-09-15 08:53:56
堆的概念
堆是一种特殊的树形数据结构,其中每个节点的值都大于或等于其子节点的值。堆通常用于实现优先队列,其中优先级最高的元素位于堆的顶部。堆的典型操作包括插入、删除和查找。
堆的实现
在JavaScript中,堆可以通过数组来实现。堆的数组表示法中,每个元素都存储一个值,并且该值大于或等于其子节点的值。堆的数组表示法如下图所示:
[
10,
8, 15,
3, 9, 12,
2, 5, 7, 11
]
堆的操作
堆的主要操作包括插入、删除和查找。插入操作将一个新的元素插入堆中,删除操作从堆中删除一个元素,查找操作找到堆中的某个元素。
插入操作
插入操作将一个新的元素插入堆中。插入操作首先将新元素添加到堆的末尾,然后将新元素向上移动,直到新元素的值大于或等于其父节点的值。插入操作的时间复杂度为O(log n),其中n是堆中的元素数量。
删除操作
删除操作从堆中删除一个元素。删除操作首先将堆顶元素与堆的最后一个元素交换,然后将堆的最后一个元素删除。然后,将堆顶元素向下移动,直到堆顶元素的值大于或等于其子节点的值。删除操作的时间复杂度为O(log n),其中n是堆中的元素数量。
查找操作
查找操作找到堆中的某个元素。查找操作从堆顶元素开始,然后向下移动,直到找到要查找的元素。查找操作的时间复杂度为O(log n),其中n是堆中的元素数量。
堆的应用
堆在计算机科学中有很多应用,包括排序、查找、插入和删除。
排序
堆可以用于对数组进行排序。堆排序是一种非递归的排序算法,其时间复杂度为O(n log n),其中n是数组中的元素数量。堆排序的实现如下:
function heapSort(array) {
// 构建堆
for (let i = Math.floor(array.length / 2) - 1; i >= 0; i--) {
heapify(array, i, array.length);
}
// 排序
for (let i = array.length - 1; i > 0; i--) {
// 将堆顶元素与最后一个元素交换
[array[0], array[i]] = [array[i], array[0]];
// 调整堆
heapify(array, 0, i);
}
return array;
}
function heapify(array, i, n) {
// 左子节点的索引
let left = 2 * i + 1;
// 右子节点的索引
let right = 2 * i + 2;
// 最大元素的索引
let largest = i;
// 如果左子节点的值大于父节点的值,则将最大元素的索引更新为左子节点的索引
if (left < n && array[left] > array[i]) {
largest = left;
}
// 如果右子节点的值大于最大元素的值,则将最大元素的索引更新为右子节点的索引
if (right < n && array[right] > array[largest]) {
largest = right;
}
// 如果最大元素的索引不是父节点的索引,则将父节点的值与最大元素的值交换,并递归地调整堆
if (largest !== i) {
[array[i], array[largest]] = [array[largest], array[i]];
heapify(array, largest, n);
}
}
查找
堆可以用于查找数组中的某个元素。查找操作从堆顶元素开始,然后向下移动,直到找到要查找的元素。查找操作的时间复杂度为O(log n),其中n是数组中的元素数量。
插入
堆可以用于向数组中插入一个新的元素。插入操作首先将新元素添加到堆的末尾,然后将新元素向上移动,直到新元素的值大于或等于其父节点的值。插入操作的时间复杂度为O(log n),其中n是数组中的元素数量。
删除
堆可以用于从数组中删除一个元素。删除操作首先将堆顶元素与堆的最后一个元素交换,然后将堆的最后一个元素删除。然后,将堆顶元素向下移动,直到堆顶元素的值大于或等于其子节点的值。删除操作的时间复杂度为O(log n),其中n是数组中的元素数量。
总结
堆是一种树形数据结构,其中每个节点的值都大于或等于其子节点的值。堆在计算机科学中有很多应用,包括排序、查找、插入和删除。堆的实现可以通过数组来实现,其时间复杂度为O(log n)。