Вы находитесь на странице: 1из 10

Binary heap

There are several types of heaps, but in the current article we are going to discuss
the binary heap. For short, let's call it just "heap". It is used to implement priority
queue ADT and in the heapsort algorithm. Heap is a complete binary tree, which
answers to the heap property.

Complete binary tree

It is said, that binary tree is complete, if all its levels, except possibly the deepest,
are complete. Thought, incomplete bottom level can't have "holes", which means
that it has to be fulfilled from the very left node and up to some node in the middle.
See illustrations below.

Correct example of a complete binary tree

Incorrect case, middle level is incomplete

Incorrect case, bottom level has a "hole"

Height of a complete binary tree is O(log n).


Heap property

There are two possible types of binary heaps: max heap and min heap. The
difference is that root of a min heap contains minimal element and vice versa.
Priority queue is often deal with min heaps, whereas heapsort algorithm, when
sorting in ascending order, uses max heap.

Heap property for min heap

For every node in a heap, node's value is lesser or equal, than values of the
children.

Heap property for max heap

For every node in a heap, node's value is greater or equal, than values of the
children.

To maintain simplicity, in the articles below we consider min-heap only.


Array-based internal representation.
Heap is a binary tree and therefore can be stored inside the computer using links.
It gives various benefits ; one of them is the ability to vary number of elements in a
heap quite easily. On the other hand, each node stores two auxiliary links, which
implies an additional memory costs. As mentioned above , a heap is a complete
binary tree, which leads to the idea of storing it using an array. By utilizing array-
based representation, we can reduce memory costs while tree navigation remains
quite simple.

As for the heapsort algorithm, array-based implementation is kind of native.

Mapping heap to array

A heap is stored in array level by level. The topmost level contains root only. It is
mapped to the first element of an array (with index 0). Root's children are mapped
to the second and third elements and so on. A heap is a complete binary tree,
which guarantees, that heap's nodes take up places in the array compactly,
making the mapping quite efficient.

Such mapping answers to formulas below:

Left(i) = 2 * i + 1 Right(i) = 2 * i + 2 Parent(i) = (i - 1) / 2

You can see now, that navigation over a heap, mapped to an array, is, actually,
very easy.

Code snippets
Java implementation

public class BinaryMinHeap {


private int[] data;
private int heapSize;

public BinaryMinHeap(int size) {


data = new int[size];
heapSize = 0;
}

public int getMinimum() {


if (isEmpty())
throw new HeapException("Heap is empty");
else
return data[0];
}

public boolean isEmpty() {


return (heapSize == 0);
}

private int getLeftChildIndex(int nodeIndex) {


return 2 * nodeIndex + 1;
}

private int getRightChildIndex(int nodeIndex) {


return 2 * nodeIndex + 2;
}

private int getParentIndex(int nodeIndex) {


return (nodeIndex - 1) / 2;
}

public class HeapException extends RuntimeException {


public HeapException(String message) {
super(message);
}
}
}

Inserting an element into a heap


In this article we examine the idea laying in the foundation of the heap data
structure. We call it sifting, but you also may meet another terms, like " trickle",
"heapify", "bubble" or "percolate".

Insertion algorithm

Now, let us phrase general algorithm to insert a new element into a heap.

1. Add a new element to the end of an array;


2. Sift up the new element, while heap property is broken. Sifting is done as
following: compare node's value with parent's value. If they are in wrong
order, swap them.

Example

Insert -2 into a following heap:

Insert a new element to the end of the array:

In the general case, after insertion, heap property near the new node is broken:

To restore heap property, algorithm sifts up the new element, by swapping it with
its parent:

Now heap property is broken at the root node:


Keep sifting:

Heap property is fulfilled, sifting is over.

Source heap After -2 insertion

Complexity analysis

Complexity of the insertion operation is O(h), where h is heap's height. Taking into
account completeness of the tree, O(h) = O(log n), where n is number of elements
in a heap.

Code snippets

Java implementation

public class BinaryMinHeap {

………………..

public void insert(int value) {

if (heapSize == data.length)

throw new HeapException("Heap's underlying storage is overflow");

else {

heapSize++;

data[heapSize - 1] = value;
siftUp(heapSize - 1);

……………….

private void siftUp(int nodeIndex) {

int parentIndex, tmp;

if (nodeIndex != 0) {

parentIndex = getParentIndex(nodeIndex);

if (data[parentIndex] > data[nodeIndex]) {

tmp = data[parentIndex];

data[parentIndex] = data[nodeIndex];

data[nodeIndex] = tmp;

siftUp(parentIndex);

Removing the minimum from a heap


Removal operation uses the same idea as was used for insertion. Root's value,
which is minimal by the heap property, is replaced by the last array's value. Then
new value is sifted down, until it takes right position.

Removal algorithm

1. Copy the last value in the array to the root;


2. Decrease heap's size by 1;
3. Sift down root's value. Sifting is done as following:
o if current node has no children, sifting is over;
o if current node has one child: check, if heap property is broken, then
swap current node's value and child value; sift down the child;
o if current node has two children: find the smallest of them. If heap
property is broken, then swap current node's value and selected child
value; sift down the child.

Example

Remove the minimum from a following heap:


Copy the last value in the array to the root and decrease heap's size by 1:

Now heap property is broken at root:

Root has two children. Swap root's value with the smallest:

Heap property is broken in node 1:


Recover heap property:

Node 3 has no children. Sifting is complete.

Source heap After minimum removal

Complexity analysis

Complexity of the removal operation is O(h) = O(log n), where h is heap's


height, n is number of elements in a heap.

Code snippets

Java implementation

public class BinaryMinHeap {

public void removeMin() {


if (isEmpty())
throw new HeapException("Heap is empty");
else {
data[0] = data[heapSize - 1];
heapSize--;
if (heapSize > 0)
siftDown(0);
}
}

private void siftDown(int nodeIndex) {


int leftChildIndex, rightChildIndex, minIndex, tmp;
leftChildIndex = getLeftChildIndex(nodeIndex);
rightChildIndex = getRightChildIndex(nodeIndex);
if (rightChildIndex >= heapSize) {
if (leftChildIndex >= heapSize)
return;
else
minIndex = leftChildIndex;
} else {
if (data[leftChildIndex] <= data[rightChildIndex])
minIndex = leftChildIndex;
else
minIndex = rightChildIndex;
}
if (data[nodeIndex] > data[minIndex]) {
tmp = data[minIndex];
data[minIndex] = data[nodeIndex];
data[nodeIndex] = tmp;
siftDown(minIndex);
}
}
}

Summary

A binary heap is a complete binary tree which satisfies the heap ordering property.
The ordering can be one of two types:

 the min-heap property: the value of each node is greater than or equal to the
value of its parent, with the minimum-value element at the root.
 the max-heap property: the value of each node is less than or equal to the
value of its parent, with the maximum-value element at the root.

Since a heap is a complete binary tree, it has a smallest possible height - a heap
with N nodes always has O(log N) height.

A heap is useful data structure when you need to remove the object with the
highest (or lowest) priority. A common use of a heap is to implement a priority
queue.

Using a binary heap, the runtime of both the deleteMin and insert operations is
O(log n).

insert deleteMin remove findMin


binary heap O(log n) O(log n) O(log n) O(1)

Вам также может понравиться