参考:https://www.geeksforgeeks.org/min-heap-in-java/
最小堆是如何表示的?
最小堆是一棵完全二叉树。最小堆通常表示为一个数组。根元素将在Arr[0] 处。对于任何第 i 个节点,即Arr[i]:
Arr[(i -1) / 2]返回其父节点。
Arr[(2 * i) + 1]返回其左子节点。
Arr[(2 * i) + 2]返回其右子节点。
最小堆上的操作函数:
getMin():返回最小堆的根元素。此操作的时间复杂度为O(1)。
extractMin():从 MinHeap 中移除最小元素。此操作的时间复杂度为O(Log n),因为此操作需要在移除 root 后维护堆属性(通过调用 heapify())。
insert():插入一个新的键需要O(Log n)时间。我们在树的末尾添加一个新键。如果新键大于它的父键,那么我们不需要做任何事情。否则,我们需要向上遍历以修复违反的堆属性。
几个实现:
计算节点
private int parent(int pos)
{
return pos / 2;
}
// Function to return the position of the
// left child for the node currently at pos
private int leftChild(int pos)
{
return (2 * pos);
}
// Function to return the position of
// the right child for the node currently
// at pos
private int rightChild(int pos)
{
return (2 * pos) + 1;
}
迭代计算
// Function to heapify the node at pos
private void minHeapify(int pos)
{
// If the node is a non-leaf node and greater
// than any of its child
if (!isLeaf(pos)) {
if (Heap[pos] > Heap[leftChild(pos)]
|| Heap[pos] > Heap[rightChild(pos)]) {
// Swap with the left child and heapify
// the left child
// 条件差不多,就把pos放到左边去迭代处理
if (Heap[leftChild(pos)] < Heap[rightChild(pos)]) {
swap(pos, leftChild(pos));
minHeapify(leftChild(pos));
}
// Swap with the right child and heapify
// the right child
else {
swap(pos, rightChild(pos));
minHeapify(rightChild(pos));
}
}
}
}