Lecture 9

advertisement
The Heap ADT
A heap is a complete binary tree where each node’s datum is greater than or
equal to the data of all of the nodes in the left and right subtrees.
Example 1
17
15
10
9
4
14
7
6
8
11
5
3
2
1
The relational ordering between data in parent / children nodes can be different
than >=, for example can be a “less than” ordering.
Height of a heap
Proposition: The height of a heap H storing n keys is log(n) + 1.
Justification: The number of internal nodes in a complete binary tree is at most
1 + 2 + 4 + ... + 2h-1 = 2h - 1
However, if the lowest level is not complete, the number of internal nodes can
be as little as
1 + 2 + 4 + ... + 2h-2 + 1 = 2h-1
That is, the number of internal nodes in a heap is 2h-1 <= n <= 2h - 1, which
implies that the height, h, is
log(n + 1) <= h <= log(n) + 1
Operations on heaps
All heap operations are based on the following idea:
1
2.
Make a simple structural modification of the heap (different for
different operations), which may result in a violation of the heap
condition.
Traverse the heap from the root to the bottom, or from the bottom to
the root (depending on the operation) to recover the heap condition
everywhere.
The most important operations on heaps are:
–
insertItem (item)
removeItem ()
replaceItem (item)
–
deleteItem (item)
–
–
Inserts item
Removes the root and returns the datum stored
Replaces the root with item unless this violates the
heap condition
Deletes (arbitrary) item
Linear representation of a heap
The easiest way to represent a complete binary tree is by means of a onedimensional array of size 2h+1 - 1, where h is the height of the tree. The most
attractive property of this representation is that given a position of a node, j,
positions of its parent and children can be easily defined (j / 2 is the position of
the parent, j * 2 is the position of the left child, and j *2 + 1 is the position of the
right child.
Our example 1 heap can be represented as follows:
k
1
2
3
A[k]
17 15 10
4
5
6
7
8
9
10
11
12
13
14
9
14
8
3
4
7
6
11
5
2
1
Linear representation of a heap (contd.)
The insertItem operation in this representation requires the size of the array to
be increased by one, and A[size] := newNode
17
15
10
9
4
2
14
7
k
1
3
A[k]
17 15 10
8
6
11
5
3
2
1
13
4
5
6
7
8
9
10
11
12
13
14
15
9
14
8
3
4
7
6
11
5
2
1
13
Now 13 must be walked upheap to fix the heap condition. Its parent is in 15/2,
i.e. the 7th position; then, the parent’s parent is in 7/2 position, etc.
The upheap method
Algorithm upheap (A[n], j, precedes)
Input: array A[n] representing the heap,
index of the child’s node j,
precedes, a comparator object defining the ordering relationship
Output: array A[n] with data originally in j walked up until accordingly
ordered with its parent (according to the precedes function)
int l := j
int key := A[l]
int k := l/2
while (k >= 1) and precedes(A[k], key) {
A[l] := A[k]
l := k
k := l/2
}
A[l] := key
The insertItem method
Algorithm insertItem (H, Item, precedes)
Input:
heap H[size],
item to be inserted
precedes, a comparator object defining the ordering relationship
Output: boolean variable success set to true if insertItem is successful
if H.full()
success := false
else {
success := true
size := size + 1
H[size] := Item
upheap(H[size], size, precedes) }
return success
The efficiency if insertItem operation is O(log n), where n is the number of tree
nodes.
Linear representation of a heap (contd.)
The removeItem operation decreases the size of the array by one and makes
A[1] := A[size]
1
15
10
9
4
2
14
7
k
1
3
A[k]
17 15 10
8
6
11
5
3
2
4
5
6
7
8
9
10
11
12
13
14
9
14
8
3
4
7
6
11
5
2
1
Now 1 must be walked downheap to fix the heap condition. Its children are in
positions 1*2 and 1*2 + 1. Compare to the larger of the two children and if this
child is greater, exchange the two. Continue until the heap condition is fixed.
The downheap method
Algorithm downheap (A[n], j, precedes)
Input: array A[n] representing the heap,
index of the parent’s node j,
precedes, a comparator object defining the ordering relationship
Output: array A[n] with data originally in j walked down until accordingly
ordered w.r.t both of its children (according to the precedes function)
boolean foundSpot := false
int l := j
int key := A[l]
int k := 2 * l
// get the left child first
while (k <= n) and (! foundSpot) {
if (k < n) and (! precedes (A[k+1], A[k]])
k := k + 1
if (! precedes (A[k], key))
A[l] := A[k], l := k,
k := 2 * l
else foundSpot := true
} // end while
A[l] := key
The removeItem method
Algorithm removeItem (H, precedes)
Input:
heap H[size],
precedes, a comparator object defining the ordering relationship
Output: boolean variable success set to true if removeItem is successful
if H.empty()
success := false
else {
success := true
item := H[1]
H[1] := H[size]
size := size - 1
downheap(H[size], 1, precedes)}
return success
The efficiency of removeItem operation is O(log n), where n is the number of
tree nodes.
Linear representation of a heap (contd.)
The replaceItem operation does not change the size of the array but replaces
the root node with a new one, and recovers the heap condition, if necessary.
12
15
10
9
4
2
14
7
k
1
3
A[k]
12 15 10
8
6
11
5
3
2
1
4
5
6
7
8
9
10
11
12
13
14
9
14
8
3
4
7
6
11
5
2
1
Now 12 must be walked downheap to fix the heap condition.
Linear representation of a heap (contd.)
The deleteItem operation decreases the size of the array by one and makes
A[item] := A[size]; the heap condition must be fixed after that.
Assume we want to remove 15.
17
1
10
9
4
14
7
8
6
11
5
3
2
k
1
2
3
4
5
6
7
8
9
10
11
12
13
A[k]
17
1 10
9
14
8
3
4
7
6
11
5
2
Now 1 must be walked downheap to fix the heap condition.
Download