Download presentation
Presentation is loading. Please wait.
Published byIrene Devall Modified over 9 years ago
1
DATA STRUCTURES AND ALGORITHMS Lecture Notes 9 Prepared by İnanç TAHRALI
2
2 ROAD MAP PRIORITY QUEUES (HEAPS) Model Simple Implementations Binary Heap Applications of Priority Queues d-Heaps Leftist Heaps
3
3 Review insert worst case O(logN) average case O(1) deleteMin worst case O(logN) average case O(logN) buildHeap worst case O(N) average case O(N) decreaseKey worst case O(logN) average case O(1) increaseKey worst case O(logN) average case O(logN) remove worst case O(logN) average case O(logN) Running Times of Operations for Binary Heaps
4
4 d-Heaps Nodes have at most d children Shallow Insert one comparison for each percolate DeleteMin d-1 comparisons Good when number of insertions are much greater than deletion
5
5 A 3-Heap
6
6 Leftist Heaps Support merge operation efficiently Merge O(N) for binary heaps Using arrays θ(N) Efficient implementation Pointers makes others slower Leftist heap has both a structural property and an ordering property Its difference from binary heap is that, leftist heaps are not perfectly balanced
7
7 Leftist Heaps Definition : Null path length of a node x is the length of the shortest path from x to a node without two children.
8
8 Leftist Heaps Definition : For each node: NPL of left child is not less than NPL of right child Only left tree is lefist heap
9
9 Theorem : A leftist tree with r nodes on the right path must have at least 2 r -1 nodes Proof by induction: –if r = 1, there must be at least one tree node. –otherwise, suppose that the theorem is true for 1,2,…,r. –consider a leftist tree with r+1 noes on the right path –then the root has a right subtree with r nodes on the right path, and a left subtree with at least r nodes on the right path (otherwise it would not be leftist) –applying in the inductive hypothesis to these subtrees yields a minimum of 2 r -1 nodes in each subtree –this plus the root gives at least 2 r+1 -1 nodes in the tree, prooving the theorem. So, r = O(logN)
10
10 Leftist Heap Operations Fundamental operation on leftist heaps is “merging” What about insert and deleteMin Algorithm if H1 or H2 is NULL return the other one compare the root values (assume H1 is smaller) H1->right = Merge(H1->right, H2) swap the left and right subtrees if necessary if leftist heap property is violated update the NPL of the root of H1 return H1
11
11 Leftist Heap Operations Two leftist heaps H 1 and H 2
12
12 Leftist Heap Operations Result of merging H 2 and H 1 ’s right subheap
13
13 Leftist Heap Operations Result of attaching leftist heap of previous figure as H 1 ’s right child
14
14 Leftist Heap Operations Result swapping children of H 1 ’s root
15
15 template class LeftistNode { Comparable element; LeftistNode *left; LeftistNode *right; int npl; LeftistNode(const Comparable & theElement, LeftistNode *lt=NULL, LeftistNode *rt = NULL, int np=0 ) : element( theElement ), left( lt ), right( rt ), npl( np ) { } friend class LeftistHeap ; };
16
16 template class LeftistHeap { public: LeftistHeap( ); LeftistHeap( const LeftistHeap & rhs ); ~LeftistHeap( ); bool isEmpty( ) const; bool isFull( ) const; const Comparable & findMin( ) const; void insert( const Comparable & x ); void deleteMin( ); void deleteMin( Comparable & minItem ); void makeEmpty( ); void merge( LeftistHeap & rhs ); const LeftistHeap & operator=( const LeftistHeap & rhs );
17
17 private: LeftistNode *root; LeftistNode * merge( LeftistNode *h1, LeftistNode *h2 ) const; LeftistNode * merge1( LeftistNode *h1, LeftistNode *h2 ) const; void swapChildren( LeftistNode * t ) const; LeftistNode * clone( LeftistNode *t ) const; };
18
18 /*Construct the leftist heap. template LeftistHeap ::LeftistHeap( ) { root = NULL; } /* Copy constructor. template LeftistHeap ::LeftistHeap( const LeftistHeap & rhs ) { root = NULL; *this = rhs; } /*Destruct the leftist heap. template LeftistHeap ::~LeftistHeap( ) { makeEmpty( ); }
19
19 /*Merge rhs into the priority queue. rhs becomes empty. rhs must be different from this. template void LeftistHeap ::merge( LeftistHeap & rhs ) { if( this == &rhs ) // Avoid aliasing problems return; root = merge( root, rhs.root ); rhs.root = NULL; } /*Internal method to merge two roots. template LeftistNode * LeftistHeap ::merge( LeftistNode * h1, LeftistNode * h2 ) const { if( h1 == NULL )return h2; if( h2 == NULL )return h1; if( h1->element element ) return merge1( h1, h2 ); else return merge1( h2, h1 ); }
20
20 /*Internal method to merge two roots. Assumes trees are not empty, and h1's root contains smallest item. template LeftistNode * LeftistHeap :: merge1( LeftistNode * h1, LeftistNode * h2 ) const { if( h1->left == NULL ) // Single node h1->left = h2; // Other fields in h1 already accurate else { h1->right = merge( h1->right, h2 ); if( h1->left->npl right->npl ) swapChildren( h1 ); h1->npl = h1->right->npl + 1; } return h1; }
21
21 /*Insert item x into the priority queue, maintaining heap order. template void LeftistHeap ::insert( const Comparable & x ) { root = merge( new LeftistNode ( x ), root ); } /* Remove the smallest item from the priority queue. template void LeftistHeap ::deleteMin( ) { if( isEmpty( ) ) throw Underflow( ); LeftistNode *oldRoot = root; root = merge( root->left, root->right ); delete oldRoot; }
22
22 Leftist Heap Operations Result of merging right paths of H 1 and H 2
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.