

二叉堆
二叉堆是一个完整的二叉树,用于有效地存储数据,以根据其结构获取最大或最小元素。
二叉堆是最小堆或最大堆。在最小二叉堆中,根处的键必须是二叉堆中存在的所有键中最小的。对于二叉树中的所有节点,相同的属性必须递归地为真。最大二叉堆与最小堆类似。
最小堆的示例:
10 10 / \ / \
20 100 15 30
/ / \ /
30 40 50 100 40
二叉堆是如何表示的?
二叉堆是一棵完全二叉树。二叉堆通常表示为数组。
- 根元素将位于 Arr[0]。
- 下表显示了第 i个节点,即 Arr[i] 的其他节点的索引:
到达[(i-1)/2] | 返回父节点 |
---|---|
到达[(2*i)+1] | 返回左子节点 |
到达[(2*i)+2] | 返回右子节点 |
实现数组表示的遍历方法是层序遍历。详细请参考二叉堆的数组表示。
堆上的操作:
以下是最小堆上的一些标准操作:
- getMin():返回最小堆的根元素。该操作的时间复杂度为O(1)。如果是 maxheap ,则为getMax()。
- extractMin():从 MinHeap 中删除最小元素。此操作的时间复杂度为O(log N) ,因为此操作需要在删除根后维护堆属性(通过调用heapify() )。
- DecreaseKey():减少键的值。此操作的时间复杂度为O(log N)。如果一个节点减少的键值大于该节点的父节点,那么我们不需要做任何事情。否则,我们需要向上遍历来修复违规的堆属性。
- **insert():插入新键需要O(log N)**时间。我们在树的末尾添加一个新键。如果新值大于其父值,那么就不需要执行任何操作。否则,我们需要向上遍历来修复相关的值的顺序,保证堆固有属性。
- **delete():删除一个键也需要O(log N)**时间。**我们通过调用DecreaseKey()将要删除的键替换为最小无限。在decreaseKey()之后,负无穷值必须到达根,因此我们调用extractMin()**来删除对应的值。
下面是基本堆操作的实现。
// A class for Min Heap
class MinHeap
{
// Constructor: Builds a heap from a given array a[] of given size
constructor()
{
this.arr = [];
}
left(i) {
return 2*i + 1;
}
right(i) {
return 2*i + 2;
}
parent(i){
return Math.floor((i - 1)/2)
}
getMin()
{
return this.arr[0]
}
insert(k)
{
let arr = this.arr;
arr.push(k);
// Fix the min heap property if it is violated
let i = arr.length - 1;
while (i > 0 && arr[this.parent(i)] > arr[i])
{
let p = this.parent(i);
[arr[i], arr[p]] = [arr[p], arr[i]];
i = p;
}
}
// Decreases value of key at index 'i' to new_val.
// It is assumed that new_val is smaller than arr[i].
decreaseKey(i, new_val)
{
let arr = this.arr;
arr[i] = new_val;
while (i !== 0 && arr[this.parent(i)] > arr[i])
{
let p = this.parent(i);
[arr[i], arr[p]] = [arr[p], arr[i]];
i = p;
}
}
// Method to remove minimum element (or root) from min heap
extractMin()
{
let arr = this.arr;
if (arr.length == 1) {
return arr.pop();
}
// Store the minimum value, and remove it from heap
let res = arr[0];
arr[0] = arr[arr.length-1];
arr.pop();
this.MinHeapify(0);
return res;
}
// This function deletes key at index i. It first reduced value to minus
// infinite, then calls extractMin()
deleteKey(i)
{
this.decreaseKey(i, this.arr[0] - 1);
this.extractMin();
}
// A recursive method to heapify a subtree with the root at given index
// This method assumes that the subtrees are already heapified
MinHeapify(i)
{
let arr = this.arr;
let n = arr.length;
if (n === 1) {
return;
}
let l = this.left(i);
let r = this.right(i);
let smallest = i;
if (l < n && arr[l] < arr[i])
smallest = l;
if (r < n && arr[r] < arr[smallest])
smallest = r;
if (smallest !== i)
{
[arr[i], arr[smallest]] = [arr[smallest], arr[i]]
this.MinHeapify(smallest);
}
}
}
let h = new MinHeap();
h.insert(3);
h.insert(2);
h.deleteKey(1);
h.insert(15);
h.insert(5);
h.insert(4);
h.insert(45);
console.log(h.extractMin() + " ");
console.log(h.getMin() + " ");
h.decreaseKey(2, 1);
console.log(h.extractMin());
类似的帖子

