Binary Heap
Structure¶
For the structure of the binary heap, it is a complete binary tree, in which each node stores an element (or a weight).
Property of heap: the weight of parent node is not less than the weight of child node (max heap). Similarly, we can define a min heap. This article takes the max heap as an example.
Due to the nature of the heap, the root of the tree stores the maximum value (which can be obtained using getmax operation).
Insertion operation¶
The insertion operation refers to inserting an element into the binary heap, and it is required that the tree remains a complete binary tree after insertion.
The easiest way is to insert after the rightmost leaf in the bottom layer.
If the bottom layer is full, then add another layer.
How about the property of heap cannot be satisfied after insertion?
Upward adjustment: If the weight of this node is greater than the weight of its parent node, swap and repeat this process until this condition is no longer satisfied or reaches the root.
It can be proved that after the upward adjustment in insertion operation, no other node will not satisfy the heap property.
The time complexity of the upward adjustment is
Deletion operation¶
Deletion operation refers to deleting the largest element in the heap, that is, deleting the root node.
But if deleted directly, there will be two heaps, which is difficult to handle.
So consider the reverse process of the insertion operation. That is, try to move the root to the last node, and then delete it directly.
However, it is difficult to do in practice. The method we usually use is to directly swap the root node with the last node.
So the root node (at the last node) is deleted directly, but the new root node may not satisfy the heap property...
Downward adjustment: Find the largest one among the child nodes, swap it with the root node, and repeat this process to the bottom.
It can be proved that after deletion and downward adjustment, no other node does not satisfy the heap property.
Time complexity is
Decrease the weight of a node¶
Obviously, after direct changes, you can adjust it upward once, and the time complexity is
Implementation¶
We found that several operations described above mainly rely on two principles: upward and downward adjustments.
Consider using a sequence
Sample code:
void up(inst x) {
while (x > 1 && h[x] > h[x / 2]) {
swap(h[x], h[x / 2]);
x /= 2;
}
}
void down(int x) {
while (x * 2 <= n) {
t = x * 2;
if (t + 1 <= n && h[t + 1] > h[t]) t++;
if (h[t] <= h[x]) break;
std::swap(h[x], h[t]);
x = t;
}
}
Building a heap¶
Consider this problem: starting from an empty heap, insert
Inserting directly one by one takes
Method 1: Use decreasekey (i.e. upward adjustment)¶
Starting from the root, proceed in the order of BFS.
void build_heap_1() {
for (i = 1; i <= n; i++) up(i);
}
Why doing this: For the nodes of the
Overall time complexity:
(Proved in "Comparison-based sorting")
Method 2: downward adjustment¶
Now, let's change our mind and start from the leaves and adjust downward one by one
void build_heap_2() {
for (i = n; i >= 1; i--) down(i);
}
Another way of understanding is to "merge" the two adjusted heaps each time, which shows the correctness.
Note that the time complexity of the downward adjustment is
The reason why building a heap in
It's hard to say if there are strong conditions like sorting.
buildLast update and/or translate time of this article,Check the history
editFound smelly bugs? Translation outdated? Wanna contribute with us? Edit this Page on Github
peopleContributor of this article OI-wiki
translateTranslator of this article Visit the original article!
copyrightThe article is available under CC BY-SA 4.0 & SATA ; additional terms may apply.