ALGORITHMS AND DATA
STRUCTURES
HEAP
Informatics Department
Parahyangan Catholic University
DEFINITION
A (binary) heap is an array object that can be
viewed as a nearly complete binary tree
Example:
1 2 3 4 5 6 7 8 9 2
1 0
2 1 1
8 5 9 1 6 1
0 5 7
2 1 1
5 3 7
4 8 5 5 9 6 1 7
8 6 9 1
DEFINITION
A (binary) heap is an array object that can be
viewed as a nearly complete binary tree
Example: 2
0
1 1
5 7
8 9 1
1
Not a heap !
HEAP’S ARRAY IMPLEMENTATION
2
1 2 3 4 5 6 7 8 9 1 0
2 1 1
8 5 9 1 6 1
0 5 7
2 1 1
5 3 7
i LEFT(i) RIGHT(i) 4 8 5 5 9 6 1 7
1 2 3
2 4 5
8 6 9 1
3 6 7
What if the array’s
4 8 9 index starts from
0?
LEFT(i) = 2i
PARENT(i) = ?
RIGHT(i) = 2i+1
TWO KINDS OF BINARY HEAP
Maximum-Heap
every node i except the root satisfies
A[PARENT[i]] ≥ A[i]
Minimum-Heap
every node i except the root satisfies
A[PARENT[i]] ≤ A[i]
HEAP PROPERTIES
The height of a heap with n elements is
h lg n
The number of leaf in a heap with n elements
is
n n
# leaf # internal
2 2
A binary tree with n=1 must be a heap
(thus every leaf is a heap)
BUILDING A MAXIMUM-HEAP
How do we build a heap from an arbitrary
array ?
We first consider the MAX-HEAPIFY procedure
Consider the following x
configuration. The trees rooted at
y and z satisfy the max-heap
property, but x, y, and z may not.
y z
Thus we have 3 possibilities :
• x ≥ y and z
• y ≥ x and z Hea Hea
• z ≥ x and y p p
MAX-HEAPIFY
When x ≥ y and z,
the whole tree satisfies the max-heap
property
x
y
When y ≥ x and z,
y
x z
we switch x and y,
leaving us with shorter
might-not-a-heap subtree
(repeat MAX-HEAPIFY
for x, a, and b) a b
Similar approach for Heap Heap
Heap
when z ≥ x and y Heap
MAX-HEAPIFY
The MAX-HEAPIFY takes an array A and an
index i as inputs
When MAX-HEAPIFY is called, it is assumed
that the binary tree rooted at LEFT(i) and
RIGHT(i) are max-heaps, but that A[i] might
be smaller than its children
The MAX-HEAPIFY procedure allows A[i] to
“float down” in the max-heap so that the
subtree rooted at i becomes a max-heap
MAX-HEAPIFY
MAX-HEAPIFY(A, i)
left = LEFT(i)
right = RIGHT(i)
largest = i
if left ≤ heapsize AND A[left] > A[largest]
largest = left
if right ≤ heapsize AND A[right] > A[largest]
largest = right
if largest ≠ i
SWAP(A[i], A[largest])
MAX-HEAPIFY(A, largest)
BUILDING A MAXIMUM-HEAP
Now we’re ready to build a max-heap !
are these max-heaps ?
Example:
1 2 3 4 5 6 7 8 9
1 6
1 1 1
6 1 8 4 5 1
3 2 5
2 1 3 8
NO ! 4 1
4 5 5 6 1 7
3
so we can’t call
MAX-HEAPIFY on
the root (index 1) 1 1
8 9
2 5
BUILDING A MAXIMUM-HEAP
Now we’re ready to build a max-heap !
are these max-heaps ?
Example:
1 2 3 4 5 6 7 8 9
1 6
1 1 1
6 1 8 4 5 1
3 2 5
2 1 3 8
YES !
so we can call
MAX-HEAPIFY on 4 1
4 5 5 6 1 7
index 3 and 4 since 3
both of their
children are max-
1 1
heaps 8
2
9
5
BUILDING A MAXIMUM-HEAP
Now we’re ready to build a max-heap !
Example:
1 2 3 4 5 6 7 8 9
1 6
1 1 1
6 1 8 4 5 1
3 2 5
2 1 3 8
Can we call
MAX-HEAPIFY
on index 2 ?
4 1
4 5 5 6 1 7
3
NO, because its left
subtree is not
a max-heap 1 1
8 9
2 5
BUILDING A MAXIMUM-HEAP
Remember, leaves are heaps,
and there are n leaves
2
1 2 3 4 5 6 7 8 9
1 6
1 1 1 1 1
6 1 8 4 5 8 1 4 MAX-HEAPIFY
3 5 3 2 5
2 1
1 3 8
3
MAX-HEAPIFY
4 1 1
4 5 5 8 6 1 7
5 3
1 1
8 9 4
2 5
BUILDING A MAXIMUM-HEAP
Remember, leaves are heaps,
and there are n leaves
2
1 2 3 4 5 6 7 8 9
1 6
1 1 1 1
6 1 1 5 8 1 1 4
5 3 5
2 2 MAX-HEAPIFY
2 1 1
Do we need to check 1 3
5 3
the relationship MAX-HEAPIFY
between
12 and 15 ? 4 1
1 5 5 8 6 1 7
2
5
No, because 12 was
originally the child of 15 8 1
1 9 4
before 1 “floats down”, 2
so it must be ≤ 15
BUILDING A MAXIMUM-HEAP
Remember, leaves are heaps,
and there are n leaves
2 MAX-HEAPIFY
1 2 3 4 5 6 7 8 9
1
1 6
1 1 1 1 5
6 6 6 5 8 1 1 4 MAX-HEAPIFY
5 5
2 3 2
2 1 1
6 3
5
2 3
MAX-HEAPIFY
4 1
6 5 5 8 6 1 7
2
8 1 9 4
BUILDING A MAXIMUM-HEAP
BUILD-MAXHEAP(A)
for i = heapsize/2 down to 1
MAX-HEAPIFY(A, i)
MAX-HEAPIFY may floats down A[i] as far as the
tree’s height, so it takes O(lg n)
BUILD-MAXHEAP calls MAX-HEAPIFY n/2 times, so
the time complexity is O(n lg n)
However, this bound is not tight ! More careful
counting shows that BUILD-MAXHEAP is O(n)
MAXIMUM
The max-heap property:
every node i except the root satisfies
A[PARENT[i]] ≥ A[i]
ensures that the largest element of A is
stored at the root (index #1)
We can easily implement MAXIMUM(A) as:
MAXIMUM(A)
return A[1]
EXTRACT-MAX
We usually need to find the largest element
in an array and removes it
(thus able to find the next largest element, and so on.)
How do we remove an element from a heap ?
remember that a heap must be a nearly
complete binary tree
removing the root of binary tree not only violates
the heaps’ property, but also breaks the tree into
two parts !
EXTRACT-MAX
If the root is removed, we need to replace it
with some other node
Since the tree needs to be nearly complete,
the root has to be replaced by the “last”
node
EXTRACT-MAX
The new root might be smaller than its
children
But we know that its left and right subtree
are heaps, so we can do MAX-HEAPIFY on the
root EXTRACT-MAX(A)
max = A[1]
A[1] = A[heapsize]
heapsize = heapsize-1
MAX-HEAPIFY(A, 1)
return max
heaps
what is the time
complexity ?
MAXIMUM-HEAP VS MINIMUM-HEAP
Maximum-Heap Minimum-Heap
Max-Heapify Min-Heapify
Build-MaxHeap Build-MinHeap
Maximum Minimum
Extract-Max Extract-Min
HEAP SORT
By using the heap data structure, we can sort
an array of n elements in O(n lg n) time.
Moreover, this sort is also in place, means it
requires only a constant number of extra
memory space.
HEAP SORT
Observe that EXTRACT-MAX replaces the root (A[1])
with the last element (A[n]), leaving the position
unused.
But A[n] is the desired position for the largest
element in an ordered array ! So we can store max
1in2 A[n]
3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
?
HEAP SORT
HEAP-SORT(A)
BUILD-MAXHEAP(A)
for i = A.length down to 2
SWAP(A[1], A[i])
heapsize = heapsize-1
MAX-HEAPIFY(A,1)
PRIORITY QUEUE
One of most popular applications of a heap is
its use as an efficient priority queue.
As with heaps, there are two kinds of priority
queues:
max priority queue, which based on max heap
min priority queue, which based on min heap
PRIORITY QUEUE OPERATIONS
A priority queue maintains a set S of elements.
Each element has a key.
A max priority queue supports
the following basic operations :
INSERT(x)
inserts element x to S
MAXIMUM()
returns the element in S that has the largest key
EXTRACT-MAX()
removes and returns the element in S that has the
largest key
INCREASE-KEY(x, k)
increase the key of element x to k
(assume the current key of x is at least as large as
k)
PRIORITY QUEUE OPERATIONS
A priority queue maintains a set S of
elements. Each element Thus,
has a key. we need to store
normally
something else other than just the
key
A max priority queue supports
Storing the whole element inside a
the following basic operations : is often not practical.
priority queue
INSERT(x) Usually we only store a “handle”
that points to the original element,
How do we implement this ?
which is stored outside the priority
queue.
MAXIMUM()
Same as MAXIMUM and
EXTRACT-MAX() Similarly, at of
EXTRACT-MAX the original element, we
max-heap
need to store a “handle” that points
to the corresponding queue element.
INCREASE-KEY(x, k)
How do we implement this ?
INCREASE KEY
The INCREASE-KEY procedure is similar to MAX-HEAPIFY,
but instead of moving an element down the heap, it
moves the element upwards.
these nodes were ≥ 8,
2
so they might and might not ≥ 18 0
1 1
5 7
1
8 5 9 1
8
these nodes were ≤ 8,
so they must be ≤ 18 6 1
(since 8’s key is increased,
not decreased)
INCREASE KEY
Observe that the path from some node x to the root is
always consist of a sequence of sorted keys.
So, when increasing one’s key we only need to move x
upwards until x’s parent has larger key 2
0
1 1
5
8 7
1
8 5 9 1
8
5
6 1
INCREASE KEY
INCREASE-KEY(A, i, key)
if key ≤ A[i]
return false
else
A[i] = key
while i > 1 and A[PARENT(i)] < A[i]
SWAP(A[PARENT(i)), A[i])
i = PARENT(i)
return true
INCREASE-KEY may move a key as far
as from leaf to root,
so the time complexity is O(lg n)
INSERT
Since a heap must be a nearly complete
binary tree, newly added node must located
at the very end of the heap array !
INSERT procedure can be easily implemented
by adding a -∞ node at the end of the heap
array, then increase its key to the desired
value.
INSERT(A, key)
heapsize = heapsize + 1
A[heapsize] = -∞
INCREASE-KEY(A, heapsize, key)
what is the time
complexity ?
THANK YOU!