570 likes | 585 Views
Learn about binary heaps, priority queues, and their operations. Understand the structure of a binary heap and the heap order property.
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 34 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