570 likes | 588 Views
Learn about Min-Max Heaps, a data structure supporting key operations like inserting elements and deleting with the smallest or largest key. Explore class definitions and constructors, insertion algorithms, and deletion processes in C++.
E N D
9.1 Min-Max Heaps 9.1.1 Definitions • A double-ended priority queue is a data structure that supports the following operations: • inserting an element with an arbitrary key • deleting an element with the largest key • deleting an element with the smallest key
9.1 Min-Max Heaps(Cont’) template <class KeyType> class DEPQ{ public: virtual void Insert(const Element<KeyType>&) = 0 ; virtual Element<KeyType>*DeleteMax(Element<KeyType>&) = 0 ; virtual Element<KeyType>*DeleteMin(Element<KeyType>&) = 0 ; }; Program 9.1 : Class definition of a double_ended priority queue
9.1 Min-Max Heaps(Cont’) • Definition of Min-Max Heap • Complete binary tree of elements such that if it is not empty, each element has a data member called key. • Alternating levels are min levels and max levels, respectively. • The root is on a min level. • If x is on a min(max) level then the element in x has the minimum (maximum) key from among all elements in its subtree. • A node on a min(max) level is called a min(max) node.
7 min 70 40 max 30 9 10 15 min 45 50 30 20 12 max 9.1 Min-Max Heaps(Cont’) Figure 9.1 : A 12-element min-max heap
3.1 Templates in C++(Cont’) templete <class keyType>class MinMaxHeap : public DEPQ<keyType>{public: MinMaxHeap(const int); //constructor ~MinMaxHeap(); //destructor void Insert(const Element<KeyType>&); Element<KeyType>* DeleteMax(Element<KeyType>&); Element<KeyType>* DeleteMin(Element<KeyType>&); private: Element<KeyType *h; int n; //Current size of the min-max heap int MaxSize; //Maximum allowable size of the min-max heap // Other private members used for implementing MinMaxHeap operations . . }; template <class KeyType> // constructor definition MinMaxHeap<KeyType>::MinMaxHeap(const int sz = DefaultHeapSize)
9.1 Min-Max Heaps(Cont’) :Maxsize(sz), n(0){ h = new Element<KeyType>[MaxSize+1]; //h[0] is not used} Program 9.2 : Class definition and constructor of a minmax heap
9.1 Min-Max Heaps(Cont’) • 9.1.2 Insertion into a Min-Max Heap • Examples • insert the element. • add the new element to the new last node. • adjust the path from j to the root.
7 min 70 40 max 30 9 10 15 min 45 50 30 20 12 j max 9.1 Min-Max Heaps(Cont’) Figure 9.2: Min-max heap of Figure 9.1 with new node j
9.1 Min-Max Heaps(Cont’) min min 15 7 max max 70 40 70 80 min min 30 9 7 15 30 9 10 15 max max 45 50 30 20 12 10 45 50 30 20 12 40 (b) min-max heap of Figure 9.1 after inserting 80 (a) min-max heap of Figure 9.1 after inserting 5 Figure 9.3: Insertion into a min-max heap
9.1 Min-Max Heaps(Cont’) templete <class keyType>void MinMaxHeap<KeyType>::Insert(const Element<KeyType>& x)// Insert x into the min-max heap h.{ if(n==MaxSize) {MinMaxFull(); return;} n++; int p=n/2; //p is the parent of the new node if (!p) {h[1]=x; return;} //insertion into an initially empty heap switch(level(p)) { case MIN: if(x.key<h[p].key) { //follow min levels h[n] = h[p]; VerifyMin(p,x); } else VerifyMax(n,x); //follow max levels break; case MAX: if(x.key>h[p].key) { //follow max levels
9.1 Min-Max Heaps(Cont’) H[n] = h[p]; VerifyMax(p,x); } else VerifyMin(n,x); //follow min levels } //end of switch} //end of Insert Program 9.3: Insertion into a min-max heap
9.1 Min-Max Heaps(Cont’) template<class KeyType> void MinMaxheap<KeyType>::VerifyMax(int i, const Element<KeyType>& x) //Follow max nodes from the max node i to the rootand insert x at proper place. { for(int gp = i / 4; // grandparent of i gp &&(x.key > h[gp].key); gp /=4) { //move h[gp] to h[i] h[i] = h[gp]; i = gp; } h[i] = x; //x is to be inserted into node i } Program 9.4: Searching for the correct max node for insertion
9.1 Min-Max Heaps(Cont’) 9.1.3 Deletion of the Min element • Delete the smallest element. • Example • delete key 7 in the root from the Fig. 9.1 • move the last node to the root • reduce the heap size by 1 • adjust the tree
12 min 70 40 max 30 9 10 15 min 45 50 30 20 max 9.1 Min-Max Heaps(Cont’) Figure 9.4: Shape of Figure 9.1 following deletion of the min item
9.1 Min-Max Heaps(Cont’) Deletion algorithm : reinsert of x on the root • (1) The root has no children. • (2) The root has at least one child. • Find the smallest key(k) in the children or grandchildren • (a) x.key h[k].key • x may be inserted into the root • (b) x.key > h[k].key , k is a child • • k is a max node • • h[k] may be moved to the root • • insert x into node k
9.1 Min-Max Heaps(Cont’) • (c) x.key > h[k].key , k is a grandchild • • move h[k] to the root • • let p be the parent of k • • if x.key > h[p].key, then h[p] and x are interchanged • • recursion of the algorithm
9 min 70 40 max 30 10 15 12 min 45 50 30 20 max 9.1 Min-Max Heaps(Cont’) Figure 9.5: Figure 9.4 following the move of the element with key 9
9.1 Min-Max Heaps(Cont’) template<class KeyType> Element<KeyType>* MinMaxHeap<KeyType>::DeleteMin(Element<KeyType> & y)// Delete and return an element with minimum key from the min-max heap{ if(!n) {MinMaxEmpty(); return 0; }// Save root and last element; update heap size y = h[1]; Element<KeyType> x = h[n--]; // Initialize for reinsertion of x int i =1, j = n/2; // Find place to insert x While(i <= j) { // i has a child, case(2) int k = MinChildGrandChild(i); if (x.key <= h[k].key) break; // case2(a), x is to be inserted into h[i] else{ // case 2(b) or ( c )
9.1 Min-Max Heaps(Cont’) h[i] = h[k]; if (k<=2*i+1) break; // k is a child of i, case 2(b) else{ // k is a grandchild of i, case 2( c ) int p = k/2; // parent of k if (x.key > h[p].key){ Element<KeyType> t = h[p]; h[p] = x; x = t; } } // end of if (k<=2*i+1) i = k; } // end of if (x.key <= h[p].key) } // end of while h[i] = x; return &y; } // end of DeleteMin Program 9.5: Deleting the element with minimum key
9.2 DEAPS 9.2.1 Definition • Deap : double-ended heap • The root contains no element • The left subtree is a min heap • The right subtree is a max heap • If the right subtree is not empty, then let i be any node in the left subtree. Let j be the corresponding node in the right subtree. If such a j does not exist, then let j be the node in the right subtree that corresponds to the parent of i. The key in node i is less than or equal to that in j.
5 45 10 8 25 40 15 19 9 30 20 9.2 DEAPS Figure 9.6: An ll-element deap
9.2 DEAPS(Cont’) • Let i be in min heap Corresponding node j of i in max heap • j = i + 2log2i - 1 • if (j > n), then j = j/2
9.2 DEAPS(Cont’) template <class KeyType> class Deap : public DEPQ<KeyType> { public: Deap (const int); ~Deap( ); void Insert(const Element<KeyType>&); Element<KeyType>* DeleteMin(Element<KeyType>&); Element<KeyType>* DeleteMax(Element<KeyType>&); private: Element<KeyType> *d; int n; // current size of Deap int MaxSize; // Other private member functions of Deap follow // Other private member functions of Deap follow . . }; template <class KeyType>Deap<KeyType>::Deap (const int sz = DefaultHeapSize) :Maxsize (sz), n(0)
9.2 DEAPS(Cont’) :Maxsize (sz), n(0) { d = new Element<KeyType> [MaxSize + 2]; // d[0] and d[1] are not used } Program 9.6 : Class definition and constructor of a deap
5 45 10 8 25 40 15 19 9 30 20 j i 9.2 DEAPS 9.2.2 Insertion into a Deap Figure 9.7: Shape of a 12-element deap
4 45 5 8 25 40 15 10 9 30 20 19 9.2 DEAPS Figure 9.8: Deap of Figure 9.6 following the insertion of 4
5 45 10 8 30 40 15 19 9 30 20 25 9.2 DEAPS Figure 9.9: Deap of Figure 9.6 following the insertion of 30
9.2 DEAPS(Cont’) • Insert Algorithm • Deap::DeapFull() • signals an error • The insertion cannot proceed, as there is no space in the deap to accommodate the additional element • Deap::MaxHeap(int p ) • a boolean function that returns the value TRUE iff p is a position in the max heap of the deap • Deap::MinPartner(int p ) • computes the min heap node that corresponds to the max heap position p. This is given by • Deap::MaxPartner(int p ) • computes the max heap node that corresponds to the parent of the min heap position p. This is given by
9.2 DEAPS(Cont’) • Deap::MinInsert and Deap::MaxInsert • insert an element into a specfied position of a min and max heap, respectively, by following the path from this position toward the root of the respective heap
9.2 DEAPS(Cont’) template <class KeyType> void Deap<KeyType>::Insert(const Element<KeyType>& x) { // Insert x into the deap int i; if (n == MaxSize) {DeapFull( ); return;} n++; if (n == 1) { d[2] = x; return; } // insertion into an empty deap int p = n + 1; // p is the new last position of the deap switch (MaxHeap(p)) { case TRUE: // p is a position in the max heap i = MinPartner(p); if(x.key<d[i].key){ d[p]=d[i]; MinInsert(i,x); } else MaxInsert(p,x); break;
9.1 Min-Max Heaps(Cont’) case FALSE: // p is a position in the min heap i=MaxPartner(p); if(x.key>d[i].key){ d[p]=d[i]; MaxInsert(i,x); } else MinInsert(p,x); } // end of the switch statement } // end of Insert Program 9.7: Inserting into a deap
8 45 10 9 25 40 15 19 20 30 9.2 DEAPS Figure 9.10: Deap of Figure 9.6 following deletion of the min element
9.2 DEAPS templete <class keyType> Element<KeyType>* Deap<KeyType>:: DeleteMin(Element<KeyType>& x); // Delete and return the min element from the deap. { if(!n) { DeapEmpty(); return 0;} x = d[2]; p = n+ 1; Element<KeyType> t = d[p]; n--; for(int i =2; i has a child; i = j) { Let j be the child with smaller key; d[i] = d[j]; } Do a deap insertion of t at position i; return &x; } // end of DeleteMin Program 9.8: Deleting the min element
A G B C I H D E F J (a) (b) 9.3 LEFTIST TREES Figure 9.11: Two binery trees
9.3 LEFTIST TREES(Cont’) 2 2 G A 1 2 1 1 B C I H 1 1 1 1 D E F J (b) (a) Figure 9.12: Extended binary trees corresponding to Figure 9.11
9.3 LEFTIST TREES(Cont’) template <class KeyType> class MinLeftistTree; // forward declaration template <class KeyType> class LeftistNode { friend class MinLeftistTree<KeyType>; private: Element<KeyType> data; LeftistNode *LeftChild, *RightChild; int shortest; }; template <class KeyType> class MinLeftistTree : public MinPQ<KeyType> { public: // constructor MinLeftistTree(LeftistNode<keyType> *init = 0) root(init){}; // the three min-leftist tree operations void Insert(const Element<KeyType>&); Element<KeyType>* DeleteMin(Element<KeyType>&); void MinCombine(MinLeftistTree<KeyType>*);
9.3 LEFTIST TREES(Cont’) Private: LeftistNode<KeyType>* MinUnion(LeftistNode<keyType>&)* LeftistNode<KeyType>*); LeftistNode<KeyType> *root; }; Program 9.9 : Class definition of a leftist tree
2 2 5 2 1 1 1 1 7 50 8 9 1 2 1 1 11 12 10 80 1 1 1 1 13 20 18 15 9.3 LEFTIST TREES(Cont’) (a) (b) Figure 9.13: Examples of min leftist trees
2 5 2 1 2 8 9 8 1 1 10 2 1 1 50 12 10 50 1 1 15 80 1 1 1 1 20 18 15 80 9.3 LEFTIST TREES(Cont’) (b) (a)
2 2 2 1 1 2 5 7 7 5 1 1 2 2 1 1 11 9 8 8 9 11 1 2 1 1 1 1 2 1 13 12 10 50 10 50 12 13 1 1 1 1 1 1 1 1 20 18 15 80 15 80 20 18 9.3 LEFTIST TREES(Cont’) 2 2 (c) (d) Figure 9.14: Combining the min leftist trees of Figure 9.13
9.3 LEFTIST TREES(Cont’) template <class KeyType> Void MinLeftistTree<KeyType>::MinCombine(MinLeftistTree<KeyType> *b) // Combine the min leftist tree b eith the given nim leftist tree. // b is set to the empty min leftist tree { if(!root)root = b→root; else if(b→root) root = MinUnion(root, b→root); b→root = 0; } Template<class KeyType> LeftistNode<KeyType>* MinLeftistTree<KeyType>::MinUnion(LeftistNode<KeyType> *a LeftistNode<KeyType> *b) // recursive function to combine two nonempty min leftist trees rooted // at a and b. The root of the resulting min leftist tree is returned. { // Set a to be min leftist tree with smaller root. if(a→data.key > b→data.key) {LeftistNode<KeyType> *t = a; a = b; b = t;} // Create binary tree such that the smallest key in each subtree is in the root
9.3 LEFTIST TREES(Cont’) if(!a→RightChild) a→RightChild = b; else a→RightChild = Minunion(a→RightChild, b); // leftist Tree property if(!a→LeftChild){ // interchange subtrees a→LeftChild = a→RigthChild; a→RightChild = 0; } else if(a→RightChild→shortest < a→RightChild→shortest) { // interchange subtrees LeftistNode<KeyType> *t = a→LeftChild; a→LeftChld = a→RightDhild; a→RightChild = t; } // Set shortest data mamber if (a!→RightChld) a→shortest = 1; else a→shortest = a→RightChild → shortest + 1; return a; } Program 9.10 : Combining two min leftist trees
3 1 8 16 10 5 4 12 7 15 30 9 6 20 9.4 BINOMIAL HEAPS Figure 9.15: A B-heap eith three min trees
9.4 BINOMIAL HEAPS(Cont’) template <class KeyType> class BinomialTree; // forward declaration Tempate <class KeyType> Class BinomiaNode{ Friend class BinomialTree<KeyType>; Private: Element<KeyType> data; BinomialNode<KeyType> *child, *link; int degree; }; Template <class KeyType> Class BinomialTree : public MinHeap<KeyType>{ Public: BinomialTree(BinomicalNode<KeyType> *init = 0) min(init) {}; // the three binominal tree operations void Insert(const Element<keyType>&); Element<KeyType>* DeleteMin(Element<KeyType>&); void MinCombine(BinomialTree<KeyType>*; Private:
9.4 BINOMIAL HEAPS(Cont’) BinomialNode<KeyType> *min; }; Program 9.11: Class definition of a binomial tree
min 8 3 1 10 5 4 12 7 16 15 30 9 6 20 9.4 BINOMIAL HEAPS(Cont’) Figure 9.16: B-heap of Figure 9.15 showing child pointers and sibling lists
8 3 12 7 16 5 4 15 30 9 10 6 20 9.4 BINOMIAL HEAPS(Cont’) Figure 9.17: The B-heap of Figure 9.15 following the deletion of the min element
7 3 12 16 8 9 5 4 15 30 10 6 20 9.4 BINOMIAL HEAPS(Cont’) Figure 9.18: The B-heap of Figure 9.17 following the joining of the two degree-one min trees
12 3 16 4 15 30 7 5 20 8 9 6 10 9.4 BINOMIAL HEAPS(Cont’) Figure 9.19: The B-heap of Figure 9.18 following the joining of two degree-two min trees