Heaps and Heap Sort - Naval Postgraduate...
Transcript of Heaps and Heap Sort - Naval Postgraduate...
2
Sample Heap
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
root
index
left child of 44
right child of 44
Level #
1
2
3
4
3
Heap Constraints
• A heap must satisfy the following two constraints:
– Structural Constraint: Nodes in a heap with N nodes must occupy the positions numbered 0, 1, ..., N-1.
– Value Relationship Constraint: A value stored in a node must be larger than the maximum of the values stored in its left and right children.
4
Nonheaps
Heaps
Structural Constraints
• Sample heaps and nonheaps that violate the structural constraints:
5
Nonheaps
Heaps
Value Relationship Constraints
• Sample heaps and nonheaps that violate the value relationship constraints:
45
25 16
3 1222
45
12 34
11 229
90
35 24
13 1612
45
55 16
3 1258
45
25 33
34 2322
45
25 55
3 1222
6
Heap ADTpublic interface NPSHeap<E> { /** Maintains the Heap properties */ public void heapify(int i); /** Converts a non-heap array into a heap */ public void buildHeap(); /** Insert an item into the heap, such that the heap property is maintained */ public void add(E item); /** Returns, but does not remove, the root element in the heap */ public E peek() throws NPSHeapEmptyException ; /** Removes and returns the root element of the heap. * Maintains the heap property */ public E poll() throws NPSHeapEmptyException ; /** Returns the size of the heap */ public int size();
/** Clears the heap */ public void clear(); /** Tells whether or not the heap is empty */ public boolean isEmpty(); }
7
Heapify
• When heapify(i) is called, it’s assumed that the binary trees rooted at the left and right children of i are heaps, but that node i may be smaller than its children
4
14
82
7
1
16
10
9 3
i
8
Heapify
• At each step, if node i is smaller than either of its children, it is swapped with the larger of the two.
4
14
82
7
1
16
10
9 3
i
9
Heapify
• At each step, if node i is smaller than either of its children, it is swapped with the larger of the two.
4
14
82
7
1
16
10
9 3
i
10
Heapify
• At each step, if node i is smaller than either of its children, it is swapped with the larger of the two.
14
4
82
7
1
16
10
9 3
i
11
Heapify
• At each step, if node i is smaller than either of its children, it is swapped with the larger of the two.
14
8
42
7
1
16
10
9 3
i
12
Build Heap
23
17 5
12 44 3890
84 77
0
1 2
3 4 5 6
7 8
Before
23
17 5
12 44 3890
84 77
0
1 2
3 4 5 6
7 8
3
(9-2)/2 = 323
17 5
12 44 3890
84 77
0
1 2
3 4 5 6
7 8
2
23
17 44
12 5 3890
84 77
0
1 2
3 4 5 6
7 8
123
90 44
12 5 3884
17 77
0
1 2
3 4 5 6
7 8
0
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
Done
• We can apply heapify in a bottom-up manner to convert an array into a max-heap.
• Heapify is applied from position (N-2)/2 to position 0.
13
Adding an Element
• When we add an element to a heap, we place it in the first available position (I.e., after all other nodes), and then perform an up-heap procedure to restore the heap properties, swapping nodes if the child is smaller than its parent.
14
8
42
7
1
16
10
9 3
15
14
Adding an Element
• When we add an element to a heap, we place it in the first available position (I.e., after all other nodes), and then perform an up-heap procedure to restore the heap properties, swapping nodes if the child is smaller than its parent.
14
8
42
15
1
16
10
9 3
7
15
Adding an Element
• When we add an element to a heap, we place it in the first available position (I.e., after all other nodes), and then perform an up-heap procedure to restore the heap properties, swapping nodes if the child is smaller than its parent.
15
8
42
14
1
16
10
9 3
7
16
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
0 1 2 3 4 5 6 7 8
90
9023
84 44
12 5 3877
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 8
90
23 > max{84, 44}? NO, so swap.
84
23 44
12 5 3877
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 8
90
23 > max{77, 12}? NO, so swap.
84
77 44
12 5 3823
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 8
90
23 > max{17}? YES, so stop.
84
77 44
12 5 3823
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 8
90
Removing the Top Element
• When removing an element, the last element is placed at the root and a heapify is performed.
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
Before After
17
Heap Implementation
• We need to implement the abstract data structure heap into a concrete data structure.
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
Abstract Heap Structure Concrete Implementation
0 1 2 3 4 5 6 7 8
23173851277448490
18
Array Indexing
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
0 1 2 3 4 5 6 7 8
Before
90 84 44 77 12 5 38 17 23 • Implementing a Heap as an array is quite efficient.
• What are the formulas for determining the indices of the left and right children of a node? How about the parent of a node?
19
Heapify
public void heapify(int i) { int largest; int l = left(i); int r = right(i); // Check the left child
if ((l < count) && (comparator.compare(arrayHeap[l], arrayHeap[i]) > 0)) largest = l; else largest = i;
// Check the right child
if ((r < count) && (comparator.compare(arrayHeap[r], arrayHeap[largest]) > 0)) largest = r; if (largest != i) { E tmp = arrayHeap[i]; arrayHeap[i] = arrayHeap[largest]; arrayHeap[largest] = tmp; heapify(largest); }
}
20
buildHeap, add /**
* Create a heap from an arbitrary array
*/
public void buildHeap() {
int i;
for (i = parent(count-1); i >=0; i-- ) {
heapify(i);
}
}
public void add(E item) {
if (count == arrayHeap.length)
expand();
int ind = count;
count++;
while (ind > 0 && comparator.compare(arrayHeap[parent(ind)], item) < 0) {
arrayHeap[ind] = arrayHeap[parent(ind)];
ind = parent(ind);
}
arrayHeap[ind] = item;
}
21
Reminder: NPSPriorityQueue Interface
public interface NPSPriorityQueue<E extends Comparable> {
/** Adds an element to the priority queue */ public void add(E element); /** Removes all elements from the priority queue. */ public void clear( );
/** Determines whether the priority queue is empty or not. */ public boolean isEmpty( );
/** Returns the head element without removing it */ public E peek( ) throws NPSQueueEmptyException;
/** Removes and returns the head element */ public E poll( ) throws NPSQueueEmptyException;
/** Returns the number of elements in the priority queue */ public int size( );}
22
Heap as a Priority Queue
• A heap works quite well as a priority queue.
public class NPSHeapPQ<E> implements NPSPriorityQueue<E> {
NPSHeap<E> heap;
/** Constructor */
public NPSHeapPQ() {
heap = new NPSArrayHeap<E>();
}
public NPSHeapPQ(int size) {
heap = new NPSArrayHeap<E>(size);
}
public NPSHeapPQ(int size, Comparator<E> comparator) {
heap = new NPSArrayHeap<E>(size, comparator);
}
/** Add an element to the heap */
public void add(E element) {
heap.add(element);
}
�
23
Heap as a Priority Queue /** Clear the heap */ public void clear() { heap.clear(); }
/** Is the heap empty? */ public boolean isEmpty() { return heap.isEmpty(); }
/** Fetch but don’t remove the top element */ public E peek() throws NPSQueueEmptyException { return heap.peek(); }
/** Remove and return the top element */ public E poll() throws NPSQueueEmptyException { return heap.poll(); }
/** size of the priority queue */ public int size() { return heap.size(); }
�
24
Heapsort Algorithm
• How can we use the heap structure to sort N elements?
• Heapsort is carried out in two phases:
– Construction Phase: Construct a heap with given N elements.
– Extraction Phase: Pull out the value in the root successively, creating a new heap with one less element after each extraction.
25
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
0 1 2 3 4 5 6 7 8
90
9023
84 44
12 5 3877
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 8
90
23 > max{84, 44}? NO, so swap.
84
23 44
12 5 3877
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 8
90
23 > max{77, 12}? NO, so swap.
84
77 44
12 5 3823
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 8
90
23 > max{17}? YES, so stop.
84
77 44
12 5 3823
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 8
90
Extraction Phase
• After each extraction, a heap must be rebuilt with one less element. One sample extraction step:
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
0 1 2 3 4 5 6 7 8
Before After
26
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
0 1 2 3 4 5 6 7 8
Rebuild Steps
• A sequence of rebuild steps to sort the list.
90
84 44
12 5 3877
17 23
0
1 2
3 4 5 6
7 8
0 1 2 3 4 5 6 7 8
Before
90
90
84
77 44
12 5 3823
17
0
1 2
3 4 5 6
7
0 1 2 3 4 5 6 7 89084
8477
23 44
12 5 3817
0
1 2
3 4 5 6
0 1 2 3 4 5 6 7 89084
77
77
44
23 38
12 517
0
1 2
3 4 5
0 1 2 3 4 5 6 7 8908477
44
44
38
23 5
1217
0
1 2
3 4
0 1 2 3 4 5 6 7 890847744
38
38
23
17 5
12
0
1 2
3
0 1 2 3 4 5 6 7 89084774438
23
23
17
12 5
0
1 2
0 1 2 3 4 5 6 7 8908477443823
17
17
12
5
0
1
0 1 2 3 4 5 6 7 890847744382317
12
12
5
0
0 1 2 3 4 5 6 7 89084774438231712
5
50 1 2 3 4 5 6 7 8
90847744382317125
Done
Sorting was completedafter 8 rebuild steps.
27
The construct Method
private void construct( ){ for (int i = (heap.length-2) / 2; i >= 0; i--) { current = i; done = false;
while ( !done ) { if ( current has no children ) { done = true; } else { if ( current node < larger child ) { swap the two nodes; set current points to the larger child; } else { done = true; }
} } }}
28
The extract Method
private void extract( ){ for (int size = heap.length-1; size >= 0; size--) { remove the root node data; move the last node to the root;
done = false; //rebuild the heap with one less element while ( !done ) { if ( current has no children ) { done = true; }
else { if ( current node < larger child ) { swap the two nodes; set current points to the larger child; } else { done = true; } }
} }}
29
Heapsort Performance
• The total number of comparisons in the extraction phase is (N-1)×K where K is the depth of a heap.
• We solve for K using the fact that the heap must satisfy the structural constraint:
∑i=1
K
2i−1=2K−1 total # nodes in a heapwith depth K
this holds becauseof the structuralconstraint
2K−1−1<N≤2K−1
K= log 2 N+1 Therefore,
N−1 ×K≃N log2N
30
Heapsort Performance
• There are N/2 rebuild steps in the construction phase.• Each rebuild step will take no more than K comparisons.• The total number of comparsions in the construction
phase is approximately
N2log 2N
Therefore, the total number of comparisons for both phases is
N2log 2N+N log 2N=O N log 2N