返回
JS图文讲解堆以及实现
前端
2023-12-10 04:54:47
堆的数据结构
堆是一种数据结构,其中每个元素都与它的子元素之间存在某种关系。在堆中,每个元素都有一个键(key),键的值决定了该元素在堆中的位置。堆有两种类型:最大堆和小堆。
- 在最大堆中,每个节点的值都大于或等于其子节点的值。
- 在小堆中,每个节点的值都小于或等于其子节点的值。
堆通常用数组来实现。在数组中,堆的根节点位于数组的第一个元素,左子节点位于数组的第 2 个元素,右子节点位于数组的第 3 个元素,依次类推。
堆的操作
堆支持以下操作:
- 插入:将一个元素插入堆中。
- 删除:从堆中删除一个元素。
- 查找:查找堆中最大的元素或最小的元素。
- 合并:将两个堆合并成一个堆。
堆的应用
堆的应用非常广泛,常见的有:
- 堆排序:堆排序是一种基于堆的数据结构的排序算法。堆排序的平均时间复杂度为 O(n log n),最坏时间复杂度为 O(n^2)。
- 优先队列:优先队列是一种数据结构,其中元素按照其优先级排序。优先队列通常用堆来实现。
- 第K大元素:第K大元素问题是指在给定数组中找到第K大的元素。第K大元素问题可以通过堆来解决。
堆的实现
以下是用 JavaScript 实现的堆:
class Heap {
constructor(type) {
this.type = type; // "max" or "min"
this.heap = [];
}
insert(value) {
this.heap.push(value);
this.heapifyUp();
}
delete() {
if (this.heap.length === 0) {
return null;
}
const root = this.heap[0];
this.heap[0] = this.heap[this.heap.length - 1];
this.heap.pop();
this.heapifyDown();
return root;
}
find() {
if (this.heap.length === 0) {
return null;
}
return this.heap[0];
}
merge(otherHeap) {
this.heap = this.heap.concat(otherHeap.heap);
this.heapify();
}
heapifyUp() {
let currentIndex = this.heap.length - 1;
while (currentIndex > 0) {
const parentIndex = Math.floor((currentIndex - 1) / 2);
if (this.type === "max") {
if (this.heap[currentIndex] > this.heap[parentIndex]) {
[this.heap[currentIndex], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[currentIndex]];
}
} else if (this.type === "min") {
if (this.heap[currentIndex] < this.heap[parentIndex]) {
[this.heap[currentIndex], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[currentIndex]];
}
}
currentIndex = parentIndex;
}
}
heapifyDown() {
let currentIndex = 0;
while (currentIndex < this.heap.length) {
const leftChildIndex = 2 * currentIndex + 1;
const rightChildIndex = 2 * currentIndex + 2;
if (this.type === "max") {
if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] > this.heap[currentIndex]) {
[this.heap[currentIndex], this.heap[leftChildIndex]] = [this.heap[leftChildIndex], this.heap[currentIndex]];
currentIndex = leftChildIndex;
} else if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] > this.heap[currentIndex]) {
[this.heap[currentIndex], this.heap[rightChildIndex]] = [this.heap[rightChildIndex], this.heap[currentIndex]];
currentIndex = rightChildIndex;
} else {
break;
}
} else if (this.type === "min") {
if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] < this.heap[currentIndex]) {
[this.heap[currentIndex], this.heap[leftChildIndex]] = [this.heap[leftChildIndex], this.heap[currentIndex]];
currentIndex = leftChildIndex;
} else if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] < this.heap[currentIndex]) {
[this.heap[currentIndex], this.heap[rightChildIndex]] = [this.heap[rightChildIndex], this.heap[currentIndex]];
currentIndex = rightChildIndex;
} else {
break;
}
}
}
}
heapify() {
for (let i = Math.floor(this.heap.length / 2) - 1; i >= 0; i--) {
this.heapifyDown(i);
}
}
}
总结
堆是一种非常重要的数据结构,在计算机科学中有广泛的应用。希望通过本文,您能够对堆有更深入的了解,并能够将其应用到您的项目中。