DESIGN & ANALYSIS OF ALGORITHM
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
0 1
5 1
7 8 5 9 1 6 1
2 0
1 5
1 7
8 5 9 1
6 1
1
2 3
4 5 6 7
8 9
DEFINITION
A (binary) heap is an array object that can be viewed as a nearly complete binary tree
Example: 2
0
1 5
1 7
8 9 1
Not a heap ! 1
HEAP’S ARRAY IMPLEMENTATION
1 2 3 4 5 6 7 8 9
2
0 1
5 1
7 8 5 9 1 6 1
2 0
1 5
1 7
8 5 9 1
6 1
1
2 3
4 5 6 7
8 9
i LEFT(i) RIGHT(i)
1 2 3
2 4 5
3 6 7
4 8 9
LEFT(i) = 2i RIGHT(i) = 2i+1
LEFT(i) = 2i
RIGHT(i) = 2i+1 PARENT(i) = ?PARENT(i) = ?
What if the array’s index starts from
0 ?
What if the array’s index starts from
0 ?
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
The number of leaf in a heap with n elements is
A binary tree with n=1 must be a heap (thus every leaf is a heap)
n
h lg
2
# n
leaf
2
# n
internal
BUILDING A MAXIMUM-HEAP
How do we build a heap from an arbitrary array ?
We first consider the MAX-HEAPIFY procedure
x
Hea p
Hea p
y z
Consider the following
configuration. The trees rooted at y and z satisfy the max-heap
property, but x, y, and z may not.
Thus we have 3 possibilities :
• x ≥ y and z
• y ≥ x and z
• z ≥ x and y
MAX-HEAPIFY
When x ≥ y and z,
the whole tree satisfies the max-heap property
When y ≥ x and z, we switch x and y,
leaving us with shorter might-not-a-heap subtree
Similar approach for when z ≥ x and y
x
Heap Heap
Heap Heap
a b
y z
y x
(repeat MAX-HEAPIFY for x, a, and b) (repeat MAX-HEAPIFY
for x, a, and b)
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) 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)
Now we’re ready to build a max-heap !
Example:
BUILDING A MAXIMUM-HEAP
1 2 3 4 5 6 7 8 9
6 1 8 4 5 1
3 1 1
2 1 5
6
1 8
4 5 1
3 1
1 2
1 5
1
2 3
4 5 6 7
8 9
are these max-heaps ?
NO !
so we can’t call MAX-HEAPIFY on the root (index 1)
NO !
so we can’t call MAX-HEAPIFY on the root (index 1)
Now we’re ready to build a max-heap !
Example:
BUILDING A MAXIMUM-HEAP
1 2 3 4 5 6 7 8 9
6 1 8 4 5 1
3 1 1
2 1 5
6
1 8
4 5 1
3 1
1 2
1 5
1
2 3
4 5 6 7
8 9
are these max-heaps ?
YES !
so we can call MAX-HEAPIFY on index 3 and 4 since
both of their children are max-
heaps YES !
so we can call MAX-HEAPIFY on index 3 and 4 since
both of their children are max-
heaps
Now we’re ready to build a max-heap !
Example:
BUILDING A MAXIMUM-HEAP
1 2 3 4 5 6 7 8 9
6 1 8 4 5 1
3 1 1
2 1 5
6
1 8
4 5 1
3 1
1 2
1 5
1
2 3
4 5 6 7
8 9
Can we call MAX-HEAPIFY
on index 2 ? Can we call MAX-HEAPIFY
on index 2 ? NO, because its left
subtree is not a max-heap
NO, because its left subtree is not
a max-heap
BUILDING A MAXIMUM-HEAP
Remember, leaves are heaps, and there are leaves
1 2 3 4 5 6 7 8 9
6 1 8 4 5 1
3 1 1
2 1 5
6
1 8
4 5 1
3 1
1 2
1 5
1
2 3
4 5 6 7
8 9
MAX-HEAPIFY MAX-HEAPIFY
1 5
4
1 2 3 4 5 6 7 8 9
6 1 8 1
5 5 1
3 1 1
2 4 MAX-HEAPIFYMAX-HEAPIFY
1 3
8
1 2 3 4 5 6 7 8 9
6 1 1
3 1
5 5 8 1 1
2 4
2 n
BUILDING A MAXIMUM-HEAP
Remember, leaves are heaps, and there are leaves
6
1 1
3
1
5 5 8 1
1
2 4
1
2 3
4 5 6 7
8 9
MAX-HEAPIFY MAX-HEAPIFY
1 2 3 4 5 6 7 8 9
6 1 1
3 1
5 5 8 1 1
2 4
1
1 5
MAX-HEAPIFY MAX-HEAPIFY
1
1 2
1 2 3 4 5 6 7 8 9
6 1
5 1
3 1 5 8 1 1
2 4
1 2 3 4 5 6 7 8 9
6 1
5 1
3 1
2 5 8 1 1 4
Do we need to check the relationship
between 12 and 15 ?
No, because 12 was originally the child of 15
before 1 “floats down”, so it must be ≤ 15 No, because 12 was originally the child of 15
before 1 “floats down”, so it must be ≤ 15
2 n
BUILDING A MAXIMUM-HEAP
Remember, leaves are heaps, and there are leaves
6
1 5
1 3
1
2 5 8 1
1 4
1
2 3
4 5 6 7
8 9
MAX-HEAPIFY MAX-HEAPIFY
1 2 3 4 5 6 7 8 9
6 1
5 1
3 1
2 5 8 1 1 4
1 5
6
MAX-HEAPIFY MAX-HEAPIFY
1 2 3 4 5 6 7 8 9
1
5 6 1
3 1
2 5 8 1 1 4
6
1 2
1 2 3 4 5 6 7 8 9
1
5 1
2 1
3 6 5 8 1 1 4
6
1 2 3 4 5 6 7 8 9
1
5 1
2 1
3 6 5 8 1 1 4
MAX-HEAPIFY MAX-HEAPIFY
2 n
BUILDING A MAXIMUM-HEAP
BUILD-MAXHEAP(A)
for i = heapsize/2 down to 1 MAX-HEAPIFY(A, i)
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]
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
heaps heaps
EXTRACT-MAX(A) max = A[1]
A[1] = A[heapsize]
heapsize = heapsize-1 MAX-HEAPIFY(A, 1)
return max EXTRACT-MAX(A)
max = A[1]
A[1] = A[heapsize]
heapsize = heapsize-1 MAX-HEAPIFY(A, 1)
return max
what is the time complexity ? 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 in A[n]
1 2 3 4 5 6 7 8 9 1 2 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)
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 has a key.
A max priority queue supports the following basic operations :
INSERT(x)
How do we implement this ?
MAXIMUM()
EXTRACT-MAX()
INCREASE-KEY(x, k)
How do we implement this ?
Same as MAXIMUM and EXTRACT-MAX of max-heap
Thus, normally we need to store something else other than just the key
Thus, normally we need to store something else other than just the key
Storing the whole element inside a priority queue is often not practical.
Usually we only store a “handle”
that points to the original element, which is stored outside the priority queue.
Similarly, at the original element, we need to store a “handle” that points to the corresponding queue element.
Storing the whole element inside a priority queue is often not practical.
Usually we only store a “handle”
that points to the original element, which is stored outside the priority queue.
Similarly, at the original element, we need to store a “handle” that points to the corresponding queue element.
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.
2 0
1 5
1 7
8 5 9 1
6 1
1 8
these nodes were ≤ 8, so they must be ≤ 18 (since 8’s key is increased, not decreased)
these nodes were ≥ 8, so they might and might not ≥ 18
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 5
1 7
8 5 9 1
6 1
1 8 1 5
1 8
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(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) 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) INSERT(A, key)
heapsize = heapsize + 1 A[heapsize] = -∞
INCREASE-KEY(A, heapsize, key)
what is the time complexity ? what is the time
complexity ?
HANDLE EXAMPLE
1 2 3 4 5 6
key = 20 person = 5
key = 15 person = 2
key = 17 person = 1
key = 8 person = 4
key = 5 person = 0
key = 9 person = 3
2 0
1 5
1 7
8 5 9
5
priority 20
1
priority 17
2
priority 15
3
priority 9
4
priority 8
0
priority 5 he
ap-id x = 5
heap-idx = 6 heap
-idx = 4 heap
-idx = 3
heap-idx = 2
heap -idx =
1