* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Lecture7PL
Survey
Document related concepts
Transcript
Priority Queues and Binary Heaps 15-211 Fundamental Data Structures and Algorithms Peter Lee February 4, 2003 Announcements • HW3 is available due Monday, Feb.10, 11:59pm start today! • Quiz #1 available Thursday an online quiz requires up to one hour of uninterrupted time with a web browser must be completed by Friday, 11:59pm • HW4 in teams of two go to recitation for details Priority Queues Priority queues • Today we consider a useful abstract data type called the priority queue. Priority queue ADT • Assume we have objects x that can be compared using the < and == operators. These are Comparable objects. • insert(k, o) Inserts comparable object k into the priority queue with object o. • deleteMin() Returns and removes the minimum element from the priority queue. The priority queue interface • create • insert void insert (Comparable key, Object r) • findMin Comparable findMin () • deleteMin Comparable deleteMin () Priority Queues: Applications • Event simulations (key is time) • Shortest paths in a graph • Huffman codes • Sorting Possible priority queue implementations • Linked list deleteMin insert O(1) O(N) or O(N) O(1) • Search trees All operations • Heaps deleteMin insert O(log N) avg (assume random) worst O(log N) 2.6 O(log N) O(log N) O(N) O(N) special case: buildheap i.e., insert*N Possible priority queue implementations • Linked list deleteMin insert O(1) O(N) or O(N) O(1) • Search trees All operations • Heaps deleteMin insert O(log N) avg (assume random) worst O(log N) 2.6 O(log N) O(log N) O(N) O(N) special case: buildheap i.e., insert*N Possible priority queue implementations • Linked list deleteMin insert O(1) O(N) or O(N) O(1) • Search trees All operations • Heaps deleteMin insert O(log N) avg (assume random) worst O(log N) 2.6 O(log N) O(log N) O(N) O(N) special case: buildheap i.e., insert*N A Digression: Perfect and Complete Binary Trees Perfect binary trees 13 21 16 24 65 31 26 32 19 26 65 68 26 65 26 Perfect binary trees 13 21 16 24 31 65 65 26 26 65 32 26 65 19 26 26 65 65 26 65 26 68 26 65 65 26 65 26 26 65 26 Perfect binary trees 13 21 16 24 31 65 65 26 26 65 32 26 65 19 26 26 65 65 26 65 26 68 26 65 65 26 65 26 26 65 26 6526 6526 6526 6526 6526 6526 6526 6526 6526 6526 6526 65266526 6526 6526 6526 Perfect binary trees • How many nodes? 13 21 24 65 16 31 19 68 26 32 26 65 26 65 26 Perfect binary trees • How many nodes? N = 24 - 1 = 15 13 21 24 65 16 31 19 68 26 32 26 65 26 65 26 h=3 N=15 Perfect binary trees • How many nodes? N = 24 - 1 = 15 Most of the nodes are ______ 13 21 24 65 16 31 19 68 26 32 26 65 26 65 26 h=3 N=15 Perfect binary trees • How many nodes? N = 24 - 1 = 15 Most of the nodes are leaves 13 21 24 65 How many edges? 16 31 19 68 26 32 26 65 26 65 26 h=3 N=15 Perfect binary trees • How many nodes? N = 24 - 1 = 15 In general: N = Most of the nodes are leaves 13 21 24 65 16 31 19 h=3 N=15 68 26 32 26 65 26 65 26 Perfect binary trees • How many nodes? N = 24 - 1 = 15 In general: N = = 2h+1 - 1 Most of the nodes are leaves 13 21 24 65 16 31 19 h=3 N=15 68 26 32 26 65 26 65 26 Quiz Break Red-green quiz • In a perfect binary tree, what is the sum of the heights of the nodes? Give a mathematical characterization. Give a tight upper bound (in big-O terms) Perfect binary trees • What is the sum of the heights? S= < N = O(N) 13 21 24 65 16 31 19 68 26 32 26 65 26 65 26 h=3 N=15 Complete binary trees 13 21 24 65 26 16 31 32 19 68 Complete binary trees 1 2 3 4 8 5 9 10 6 7 Representing complete binary trees • Linked structures? 1 2 3 4 8 5 9 10 6 7 Representing complete binary trees • Linked structures? No! • Instead, use arrays! 1 2 3 4 8 5 9 10 6 7 Representing complete binary trees • Arrays Parent at position i in the array Children at positions 2i and 2i+1 1 2 3 4 8 5 9 10 6 7 Representing complete binary trees • Arrays (1-based) Parent at position i Children at 2i and 2i+1. 1 2 3 4 5 6 7 8 9 10 1 2 3 4 8 5 9 10 6 7 Representing complete binary trees • Arrays (1-based) Parent at position i Children at 2i and 2i+1. 1 2 3 4 5 6 7 8 9 10 1 2 3 4 8 5 9 10 6 7 Representing complete binary trees • Arrays (1-based) Parent at position i Children at 2i (and 2i+1). 1 2 3 4 5 6 7 8 9 10 1 2 3 4 8 5 9 10 6 7 Representing complete binary trees • Arrays (1-based) Parent at position i Children at 2i and 2i+1. public class BinaryHeap { private Comparable[] heap; private int size; public BinaryHeap(int capacity) { size=0; heap = new Comparable[capacity+1]; } . . . Representing complete binary trees • Arrays Parent at position i Children at 2i and 2i+1. • Example: find the leftmost child int left=1; for(; left<size; left*=2); return heap[left/2]; • Example: find the rightmost child int right=1; for(; right<size; right=right*2+1); return heap[(right-1)/2]; Back to Our Main Topic: Implementing Priority Queues with Binary Heaps Binary heaps: the invariant • Representation invariants 1. Structure property • Complete binary tree (i.e. the elements of the heap are stored in positions 1…size of the array) 2. Heap order property • Parent keys less than children keys Heaps • Representation invariant 1. Structure property • Complete binary tree • Hence: efficient compact representation 2. Heap order property • Parent keys less than children keys • Hence: rapid insert, findMin, and deleteMin • O(log(N)) for insert and deleteMin • O(1) for findMin The heap order property • Each parent is less than each of its children. • Hence: Root is less than every other node. (obvious proof by induction) 13 21 24 65 26 16 31 32 19 68 Operating with heaps Representation invariant: • All methods must: 1. Produce complete binary trees 2. Guarantee the heap order property • All methods may assume 1. The tree is initially complete binary 2. The heap order property holds Constructor method • All methods must: 1. Produce complete binary trees • Trivially true 2. Guarantee the heap order property • Also trivially true • This is the base case findMin () • The code public boolean isEmpty() { return size == 0; } public Comparable findMin() { if(isEmpty()) return null; return heap[1]; } • Does not change the tree Trivially preserves the invariant insert (Comparable x) • Process 1. Create a “hole” at the next tree cell for x. heap[size+1] This preserves the completeness of the tree. 2. Percolate the hole up the tree until the heap order property is satisfied. This assures the heap order property is satisfied. insert (Comparable x) • Process 1. Create a “hole” at the next tree cell for x. heap[size+1] This preserves the completeness of the tree assuming it was complete to begin with. 2. Percolate the hole up the tree until the heap order property is satisfied. This assures the heap order property is satisfied assuming it held at the outset. Percolation up public void insert(Comparable x) throws Overflow { if(isFull()) throw new Overflow(); int hole = ++size; for(; hole>1 && x.compareTo(heap[hole/2])<0; hole/=2) heap[hole] = heap[hole/2]; heap[hole] = x; } Percolation up • Bubble the hole up the tree until the heap order property is satisfied. hole = 11 HOP false 13 21 24 65 26 16 31 32 14 19 68 Not really there... Percolation up • Bubble the hole up the tree until the heap order property is satisfied. hole = 11 HOP false hole = 5 HOP false 13 21 13 16 24 31 65 26 32 14 19 68 21 16 24 14 65 26 32 31 19 68 Percolation up • Bubble the hole up the tree until the heap order property is satisfied. hole = 5 HOP false hole = 2 HOP true 13 21 13 16 24 14 65 26 32 31 done 19 68 14 16 24 21 65 26 32 31 19 68 Percolation up public void insert(Comparable x) throws Overflow { if(isFull()) throw new Overflow(); int hole = ++size; for(; hole>1 && x.compareTo(heap[hole/2])<0; hole/=2) Integer division heap[hole] = heap[hole/2]; heap[hole] = x; } deleteMin() /** * Remove the smallest item from the priority queue. * @return the smallest item, or null, if empty. */ public Comparable deleteMin( ) { if(isEmpty()) return null; Comparable min = heap[1]; heap[1] = heap[size--]; percolateDown(1); return min; } Grab min element Temporarily place last element at top !!! Percolation down • Bubble the transplanted leaf value down the tree until the heap order property is satisfied. 1 2 -14 16 24 21 65 26 32 31 19 68 31 14 24 65 26 16 21 32 19 68 Percolation down • Bubble the transplanted leaf value down the tree until the heap order property is satisfied. 2 3 31 14 24 65 26 16 21 32 19 68 14 31 24 65 26 16 21 32 19 68 Percolation down • Bubble the transplanted leaf value down the tree until the heap order property is satisfied. 3 4 14 31 24 65 26 16 21 32 19 68 14 21 24 65 26 done 16 31 32 19 68 percolateDown(int hole) private void percolateDown( int hole ) { int child = hole; Initially 1 Comparable tmp = heap[hole]; for( ; hole*2 <= size; hole=child ) Start at left child { child = hole * 2; Is there a right child? if(child!=size && heap[child+1].compareTo(heap[child]) < 0) child++; Select smaller child if(array[child].compareTo(tmp) < 0) heap[hole] = heap[child]; else break; } } heap[hole] = tmp; Bubble up if smaller than tmp Exit loop if not bubbling Finally, place the orphan deleteMin () • Observe that both components of the representation invariant are preserved by deleteMin. 1. Completeness • The last cell ( heap[size] ) is vacated, providing the value to percolate down. • This assures that the tree remains complete. 2. Heap order property deleteMin () • Observe that both components of the representation invariant are preserved by deleteMin. 1. Completeness • The last cell ( heap[size] ) is vacated, providing the value to percolate down. • This assures that the tree remains complete. 2. Heap order property deleteMin () • Observe that both components of the representation invariant are preserved by deleteMin. 1. Completeness • The last cell ( heap[size] ) is vacated, providing the value to percolate down. • This assures that the tree remains complete. 2. Heap order property • The percolation algorithm assures that the orphaned value is relocated to a suitable position. buildHeap() • Start with complete (unordered) tree • Starting from bottom, repeatedly call percolateDown() Void buildHeap () { for (int i = size/2; i>0; i--) percolateDown(i); } buildHeap() performance • At each iteration, have to do work proportional to the height of the current node • Therefore, total running time is bounded by the sum of the heights of all of the nodes Another Digression: Invariants Representation Invariants • Necessary for a clear understand an algorithm or piece of code. • The most useful kind of comment you can make in a piece of code! (Invariants) Plus ça change, plus c’est la même chose • The role of an induction hypothesis (Invariants and induction) • Induction hypothesis What you are allowed to assume • At the start • About the result values of a recursive call • About the object state when a method is called What you must deliver • At the end • Of the result values when the recursive call returns • About the object state when the method returns (Invariants and induction) • Induction hypothesis What you are allowed to assume • At the start of a loop iteration • About the result values of a recursive call • About the object state when a method is called What you must deliver • At the end of the loop iteration • Of the result values when the recursive call returns • About the object state when the method returns (Invariants and induction) • Induction hypothesis What you are allowed to assume • • About the result values of a recursive call • About the object state when a method is called What you must deliver • • Of the result values when the recursive call returns • About the object state when the method returns (Invariants and induction) • Induction hypothesis What you are allowed to assume • At the start of a loop iteration • About the result values of a recursive call • About the object state when a method is called What you must deliver • At the end of the loop iteration • Of the result values when the recursive call returns • About the object state when the method returns (Invariants and induction) • Induction hypothesis What you are allowed to assume • At the start of a loop iteration • About the result values of a recursive call • About the object state when a method is called What you must deliver • At the end of the loop iteration • Of the result values when the recursive call returns • About the object state when the method returns (Invariants) Plus ça change, plus c’est la même chose • The role of an induction hypothesis • Invariants in programs Loop invariants Recursion invariants Representation invariants (Representation invariant) • What must always be true of the data structure when an operation completes. • Theorem: Suppose each constructor assures the representation invariant is initially correct. Suppose each method preserves the representation invariant, assuming it is true initially. Then the representation invariant will always be true at the completion of each method. (Representation invariant) • What must always be true of the data structure when an operation completes. • Theorem: Suppose each constructor assures the representation invariant is initially correct. Suppose each method preserves the representation invariant, assuming it is true initially. Then the representation invariant will always be true at the completion of each method. (Representation invariants) • What must always be true of the data structure when an operation completes. • Theorem: Suppose each constructor assures the representation invariant is initially correct. Suppose each method preserves the representation invariant, assuming it is true initially. Then the representation invariant will always be true at the completion of each method. Assuming the code is not concurrent! Heapsort • Obviously we can use a priority queue to sort . . . just insert all the keys then do repeated deleteMins • However we can take advantage of the fact that the heap always uses the first part of the array to do this with no extra space. • This is called heapsort. Heapsort • Reverse the sense of the heap order (largest at the root) • Start from position 0 in the array (children are 2i+1 and 2i+2) • Call it percDown(a, i, len) Public static void heapsort(Comparable[] a) { for(int i = a.length/2; i>=0; i--) percDown(a, i, a.length); for (int j = a.length-1; j>0; j--) { swapReferences(a, 0, j); percDown(a, 0, j); } } Heapsort invariant • At the start of the loop over j: a[j]…a[a.length-1] are sorted a[0]…a[j-1] are a heap