570 likes | 598 Views
Heaps. Priority Queues. Outline. Binary heaps Binomial queues Leftist heaps. Binary Heaps. 12. 19. 22. 25. 48. 15. 27. 23. 21. 16. 28. Heap order property. For every root node N , the key in the parent of N is smaller than or equal to the key in N. 5.
E N D
Heaps Priority Queues
Outline Binary heaps Binomial queues Leftist heaps Data Structure: Heaps
12 19 22 25 48 15 27 23 21 16 28 Heap order property For every root node N, the key in the parent of N is smaller than or equal to the key in N. 5 The smallest value is in the root. Data Structure: Heaps
Operations on priority queues • Insert • Put an element into the queue • DeleteMin • Find the minimal element • Return it • Remove it from the queue Data Structure: Heaps
Binary Heaps • A binary heap is an implementation of a priority queue. • A binary heap is a complete binary tree with heap order property. Data Structure: Heaps
12 23 25 31 33 34 36 45 30 35 40 43 40 56 Complete Binary Tree A binary tree is a complete binary tree if • every level in the tree is completely filled, • except the leaf level, which is filled from left to right. 32 Height is in log2n, where n is the number of nodes. Data Structure: Heaps
B C E F G D L K H I J Array implementation of complete binary tree A 1 2 3 4 5 6 7 12 11 8 9 10 A B C D E F G H I J K L 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Data Structure: Heaps
Class BinaryHeap public class BinaryHeap { public BinaryHeap( ) { this( DEFAULT_CAPACITY ); } public BinaryHeap( int capacity ) { currentSize = 0; array = new Comparable[ capacity + 1 ]; } … private static final int DEFAULT_CAPACITY = 100; private int currentSize; // Number of elements in heap private Comparable [ ] array; // The heap array } Data Structure: Heaps
48 15 27 23 21 16 percolateUp 5 12 19 22 25 36 3 Data Structure: Heaps
Method percolateUp private void percolateUp( int hole ) { Comparable x = array[hole]; while (hole > 1 && x.compareTo( array[ hole / 2 ] ) < 0) { array[ hole ] = array[ hole/2 ]; hole = hole/2; } array[ hole ] = x; } Data Structure: Heaps
Method percolateUp private void percolateUp( int hole ) { while (hole>1 && array[hole].compareTo( array[ hole/2 ])<0) { swap(hole, hole/2); hole = hole/2; } } private void swap( int p1, int p2 ) { Comparable x = array[p1]; array[p1] = array[p2]; array[p2] = x; } Data Structure: Heaps
PercolateDown 32 12 23 25 31 33 34 36 45 30 35 40 43 40 56 Data Structure: Heaps
Method percolateDown private void percolateDown( int hole ) { int child; while( hole * 2 <= currentSize) { child = hole * 2; if(child != currentSize&&array[ child+1].compareTo( array[child ])<0) child++; // choose the smaller child if( array[ child ].compareTo( array[ hole ] ) < 0 ) swap( hole, child ); else break; hole = child; } } Data Structure: Heaps
Method percolateDown private void percolateDown( int hole ) { int child; Comparable tmp = array[ hole ]; // save the value of the node while ( hole * 2 <= currentSize ) { child = hole * 2; if(child != currentSize&&array[ child+1].compareTo( array[child ])<0) child++; // choose the smaller child if( array[ child ].compareTo( tmp ) < 0 ) { array[ hole ] = array[ child ]; // move child up hole = child; // move hole down } else break; } array[ hole ] = tmp; // put the value in the hole } Data Structure: Heaps
12 22 48 15 27 23 21 16 28 Insertion 5 19 25 10 Data Structure: Heaps
Method insert public void insert( Comparable x ) throws Overflow { if( isFull( ) ) throw new Overflow( ); array[++currentSize]=x; percolateUp(currentSize); } Data Structure: Heaps
22 15 27 23 21 16 28 DeleteMin 5 12 10 19 48 25 Data Structure: Heaps
Method deleteMin public Comparable findMin( ) { if( isEmpty( ) ) return null; return array[ 1 ]; } public Comparable deleteMin( ) { if( isEmpty( ) ) return null; Comparable minItem = findMin( ); array[ 1 ] = array[ currentSize--]; percolateDown( 1 ); return minItem; } Data Structure: Heaps
Method buildHeap private void buildHeap( ) { for( int i = currentSize / 2; i > 0; i-- ) percolateDown( i ); } 32 12 23 25 31 33 34 36 45 30 35 40 43 40 56 Data Structure: Heaps
Method decreaseKey public void decreaseKey(int p, Comparable d) throws outOfRange { if( p>currentSize ) throw new outOfRange(); array[ p ] = array[ p ] - d; percolateUp( p ); } Data Structure: Heaps
Method increaseKey public void increaseKey(int p, Comparable d) throws outOfRange { if( p>currentSize ) throw new outOfRange(); array[ p ] = array[ p ] + d; percolateDown( p ); } Data Structure: Heaps
Binomial Tree A binomial tree is defined recursively as follow: • A binomial tree of height 0, denoted by B0, is a one-node tree. • A binomial tree of height k, denoted by Bk, is formed by attaching a binomial tree Bk-1 to the root of another binomial tree Bk-1. Data Structure: Heaps
1 4 6 4 1 1 1 2 1 1 1 1 3 3 1 Property of Binomial Trees • A binomial tree of height k has 2k nodes. • The number of nodes at depth d is the binomial coefficient k d. 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 510105 1 1 61520156 1 Data Structure: Heaps
26 13 3 35 32 28 45 16 21 43 46 40 51 50 Structure • A binomial queue is a collection of heap-ordered trees, each of which is a binomial tree. 6 Data Structure: Heaps
Binomial Nodes class BinomialNode { BinomialNode( Comparable theElement ) { this( theElement, null, null ); } BinomialNode( Comparable theElement, BinomialNode lt, BinomialNode nt ) { element = theElement; Child = lt; nextSibling = nt; } Comparable element; BinomialNode Child; BinomialNode nextSibling; } Data Structure: Heaps
26 13 35 32 28 45 16 43 46 40 51 50 Examples: binomial nodes 13 Child 32 16 nextSibling 40 26 28 35 45 43 46 51 50 Data Structure: Heaps
Binomial Queues public class BinomialQueue { public BinomialQueue( ) { theTrees = new BinomialNode[ MAX_TREES ]; makeEmpty( ); } ... public void makeEmpty( ) { currentSize = 0; for( int i=0; i < theTrees.length; i++ ) theTrees[ i ] = null; } private static final int MAX_TREES = 14; private int currentSize; private BinomialNode [ ] theTrees; private int capacity( ) { return 2*theTrees.length - 1; } } Data Structure: Heaps
Method combineTrees private static BinomialNode combineTrees ( BinomialNode t1,BinomialNode t2 ) { if( t1.element.compareTo( t2.element ) > 0 ) return combineTrees( t2, t1 ); t2.nextSibling = t1.Child; t1.leftChild = t2; return t1; } 26 26 28 35 45 35 28 45 43 46 51 43 46 51 50 50 Data Structure: Heaps
Method merge (1) public void merge( BinomialQueue rhs ) throws Overflow { if( this == rhs ) return; if( currentSize+rhs.currentSize>capacity() ) throw new Overflow( ); currentSize += rhs.currentSize; BinomialNode carry = null; for( int i=0,j=1; j<=currentSize; i++,j*=2 ) { BinomialNode t1 = theTrees[ i ]; BinomialNode t2 = rhs.theTrees[ i ]; Data Structure: Heaps
Method merge (2) // No trees if (t1==null && t2==null && carry==null) {} // Only this if (t1!=null && t2==null && carry==null) {} // Only rhs if (t1==null && t2!=null && carry==null) { theTrees[i] = t2; rhs.theTrees[i] = null;} // Only carry if (t1==null && t2==null && carry!=null) { theTrees[ i ] = carry; carry = null; } // this & rhs if (t1!=null && t2==null && carry!=null) { carry = combineTrees( t1, t2 ); theTrees[i]=rhs.theTrees[i]=null; } Data Structure: Heaps
Method merge(3) // this and carry if (t1!=null && t2==null && carry!=null) { carry = combineTrees( t1, carry ); theTrees[ i ] = null; } // rhs and carry if (t1==null && t2!=null && carry!=null) { carry = combineTrees( t2, carry ); rhs.theTrees[ i ] = null; } // All three if (t1!=null && t2!=null && carry!=null) { theTrees[ i ] = carry; carry = combineTrees( t1, t2 ); rhs.theTrees[ i ] = null; } } Data Structure: Heaps
Method merge(4) for( int k=0; k < rhs.theTrees.length; k++ ) rhs.theTrees[ k ] = null; rhs.currentSize = 0; } Data Structure: Heaps
Method insert public void insert( Comparable x ) throws Overflow { BinomialQueue oneItem= new BinomialQueue( ); oneItem.currentSize = 1; oneItem.theTrees[0] = new BinomialNode( x ); merge( oneItem ); } Data Structure: Heaps
Method deleteMin(2) for( int j = minIndex - 1; j >= 0; j-- ) { deletedQueue.theTrees[ j ] = deletedTree; deletedTree = deletedTree.nextSibling; deletedQueue.theTrees[ j ].nextSibling = null; } theTrees[ minIndex ] = null; currentSize -= deletedQueue.currentSize + 1; try { merge( deletedQueue ); } catch( Overflow e ) { } return minItem; } Data Structure: Heaps
Method deleteMin public Comparable deleteMin( ) { if( isEmpty( ) ) return null; int minIndex = findMinIndex( ); Comparable minItem = theTrees[minIndex].element; BinomialNode deletedTree = theTrees[ minIndex ].child; BinomialQueue deletedQueue = new BinomialQueue( ); deletedQueue.currentSize =(1 << minIndex)-1; Data Structure: Heaps
Null Path Length • The null path length of the node X, npl(X), is the length of the shortest path from X to a node without 2 children. • npl(X) = 1 + min (npl(Y1), npl(Y2)), where Y1 and Y2 are children of X. 1 1 0 0 0 1 0 0 0 Data Structure: Heaps
Leftist Trees • A leftist tree is a binary tree such that for every node X in the tree npl(left) npl(right), where left and right are left child and right child of X. 1 1 0 0 0 1 0 0 0 Data Structure: Heaps
Examples of leftist trees 1 1 1 0 1 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 Data Structure: Heaps
Leftist Heap • A leftist heap is a leftist tree with heap order property. 4 5 8 21 12 6 31 15 23 33 Data Structure: Heaps
Leftist Tree Nodes class LeftHeapNode { LeftHeapNode( Comparable theElement ) { this( theElement, null, null ); } LeftHeapNode( Comparable theElement, LeftHeapNode lt, LeftHeapNode rt ) { element = theElement; npl = 0; left = lt; right = rt; } Comparable element; int npl; LeftHeapNode left; LeftHeapNode right; } Data Structure: Heaps
Merge Leftist Heaps 4 6 5 8 31 15 21 12 33 23 Data Structure: Heaps
8 12 15 23 Merge Leftist Heaps 8 6 15 8 12 31 15 12 23 33 23 Data Structure: Heaps
6 5 8 31 21 33 12 15 23 Merge Leftist Heaps 4 Data Structure: Heaps
Method merge1 private static LeftHeapNode merge1 ( LeftHeapNode h1, LeftHeapNode h2 ) { if( h1.left == null ) // Single node h1.left = h2; // Other fields in h1 OK else { h1.right = merge( h1.right, h2 ); if( h1.left.npl < h1.right.npl ) swapChildren( h1 ); h1.npl = h1.right.npl + 1; } return h1; } Data Structure: Heaps
Method merge public void merge( LeftistHeap rhs ) { if( this == rhs ) return; root = merge( root, rhs.root ); rhs.root = null; } private static LeftHeapNode merge( LeftHeapNode h1, LeftHeapNode h2 ) { if( h1 == null ) return h2; if( h2 == null ) return h1; if( h1.element.compareTo( h2.element ) < 0 ) return merge1( h1, h2 ); else return merge1( h2, h1 ); } Data Structure: Heaps
Methods insert, deleteMIn public void insert( Comparable x ) { root=merge(new LeftHeapNode(x),root); } public Comparable deleteMin( ) { if( isEmpty( ) ) return null; Comparable minItem = root.element; root = merge( root.left, root.right ); return minItem; } Data Structure: Heaps
Applications • Event simulation • Merge sort Data Structure: Heaps