码迷,mamicode.com
首页 > 其他好文 > 详细

【数据结构】左式堆

时间:2014-07-31 09:35:36      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   strong   io   数据   for   

复杂度:

实现:

  1 #ifndef LEFTIST_HEAP_H
  2 #define LEFTIST_HEAP_H
  3 
  4 #include "dsexceptions.h"
  5 #include <iostream>
  6 using namespace std;
  7 
  8 // Leftist heap class
  9 //
 10 // CONSTRUCTION: with no parameters
 11 //
 12 // ******************PUBLIC OPERATIONS*********************
 13 // void insert( x )       --> Insert x
 14 // deleteMin( minItem )   --> Remove (and optionally return) smallest item
 15 // Comparable findMin( )  --> Return smallest item
 16 // bool isEmpty( )        --> Return true if empty; else false
 17 // void makeEmpty( )      --> Remove all items
 18 // void merge( rhs )      --> Absorb rhs into this heap
 19 // ******************ERRORS********************************
 20 // Throws UnderflowException as warranted
 21 
 22 template <typename Comparable>
 23 class LeftistHeap
 24 {
 25   public:
 26     LeftistHeap( ) : root{ nullptr }
 27       { }
 28     LeftistHeap( const LeftistHeap & rhs ) : root{ nullptr }
 29       { root = clone( rhs.root ); }
 30     
 31     LeftistHeap( LeftistHeap && rhs ) : root{ rhs.root }
 32     {
 33         rhs.root = nullptr;
 34     }
 35     
 36     ~LeftistHeap( )
 37       { makeEmpty( ); }
 38     
 39     
 40     /**
 41      * Deep copy.
 42      */
 43     LeftistHeap & operator=( const LeftistHeap & rhs )
 44     {
 45         LeftistHeap copy = rhs;
 46         std::swap( *this, copy );
 47         return *this;
 48     }
 49         
 50     /**
 51      * Move.
 52      */
 53     LeftistHeap & operator=( LeftistHeap && rhs )
 54     {
 55         std::swap( root, rhs.root );
 56         
 57         return *this;
 58     }
 59     
 60     /**
 61      * Returns true if empty, false otherwise.
 62      */
 63     bool isEmpty( ) const
 64       { return root == nullptr; }
 65     
 66     /**
 67      * Find the smallest item in the priority queue.
 68      * Return the smallest item, or throw Underflow if empty.
 69      */
 70     const Comparable & findMin( ) const
 71     {
 72         if( isEmpty( ) )
 73             throw UnderflowException{ };
 74         return root->element;
 75     }
 76 
 77     /**
 78      * Inserts x; duplicates allowed.
 79      */
 80     void insert( const Comparable & x )
 81       { root = merge( new LeftistNode{ x }, root ); }
 82 
 83     /**
 84      * Inserts x; duplicates allowed.
 85      */
 86     void insert( Comparable && x )
 87       { root = merge( new LeftistNode{ std::move( x ) }, root ); }
 88 
 89     /**
 90      * Remove the minimum item.
 91      * Throws UnderflowException if empty.
 92      */
 93     void deleteMin( )
 94     {
 95         if( isEmpty( ) )
 96             throw UnderflowException{ };
 97 
 98         LeftistNode *oldRoot = root;
 99         root = merge( root->left, root->right );
100         delete oldRoot;
101     }
102 
103     /**
104      * Remove the minimum item and place it in minItem.
105      * Throws UnderflowException if empty.
106      */
107     void deleteMin( Comparable & minItem )
108     {
109         minItem = findMin( );
110         deleteMin( );
111     }
112 
113     /**
114      * Make the priority queue logically empty.
115      */
116     void makeEmpty( )
117     {
118         reclaimMemory( root );
119         root = nullptr;
120     }
121 
122     /**
123      * Merge rhs into the priority queue.
124      * rhs becomes empty. rhs must be different from this.
125      */
126     void merge( LeftistHeap & rhs )
127     {
128         if( this == &rhs )    // Avoid aliasing problems
129             return;
130 
131         root = merge( root, rhs.root );
132         rhs.root = nullptr;
133     }
134 
135 
136   private:
137     struct LeftistNode
138     {
139         Comparable   element;
140         LeftistNode *left;
141         LeftistNode *right;
142         int          npl;
143 
144         LeftistNode( const Comparable & e, LeftistNode *lt = nullptr,
145                         LeftistNode *rt = nullptr, int np = 0 )
146           : element{ e }, left{ lt }, right{ rt }, npl{ np } { }
147         
148         LeftistNode( Comparable && e, LeftistNode *lt = nullptr,
149                         LeftistNode *rt = nullptr, int np = 0 )
150           : element{ std::move( e ) }, left{ lt }, right{ rt }, npl{ np } { }
151     };
152 
153     LeftistNode *root;
154 
155     /**
156      * Internal method to merge two roots.
157      * Deals with deviant cases and calls recursive merge1.
158      */
159     LeftistNode * merge( LeftistNode *h1, LeftistNode *h2 )
160     {
161         if( h1 == nullptr )
162             return h2;
163         if( h2 == nullptr )
164             return h1;
165         if( h1->element < h2->element )
166             return merge1( h1, h2 );
167         else
168             return merge1( h2, h1 );
169     }
170 
171     /**
172      * Internal method to merge two roots.
173      * Assumes trees are not empty, and h1‘s root contains smallest item.
174      */
175     LeftistNode * merge1( LeftistNode *h1, LeftistNode *h2 )
176     {
177         if( h1->left == nullptr )   // Single node
178             h1->left = h2;       // Other fields in h1 already accurate
179         else
180         {
181             h1->right = merge( h1->right, h2 );
182             if( h1->left->npl < h1->right->npl )
183                 swapChildren( h1 );
184             h1->npl = h1->right->npl + 1;
185         }
186         return h1;
187     }
188 
189     /**
190      * Swaps t‘s two children.
191      */
192     void swapChildren( LeftistNode *t )
193     {
194         LeftistNode *tmp = t->left;
195         t->left = t->right;
196         t->right = tmp;
197     }
198 
199     /**
200      * Internal method to make the tree empty.
201      * WARNING: This is prone to running out of stack space;
202      *          exercises suggest a solution.
203      */
204     void reclaimMemory( LeftistNode *t )
205     {
206         if( t != nullptr )
207         {
208             reclaimMemory( t->left );
209             reclaimMemory( t->right );
210             delete t;
211         }
212     }
213     
214     /**
215      * Internal method to clone subtree.
216      * WARNING: This is prone to running out of stack space.
217      *          exercises suggest a solution.
218      */
219     LeftistNode * clone( LeftistNode *t ) const
220     {
221         if( t == nullptr )
222             return nullptr;
223         else
224             return new LeftistNode{ t->element, clone( t->left ), clone( t->right ), t->npl };
225     }
226 };
227 
228 #endif

应用:

 1 #include "LeftistHeap.h"
 2 #include <iostream>
 3 using namespace std;
 4 
 5 int main( )
 6 {
 7     int numItems = 10000;
 8     LeftistHeap<int> h;
 9     LeftistHeap<int> h1;
10     LeftistHeap<int> h2;
11     int i = 37;
12 
13     cout << "Begin test..." << endl;
14     for( i = 37; i != 0; i = ( i + 37 ) % numItems )
15         if( i % 2 == 0 )
16             h1.insert( i );
17         else
18             h.insert( i );
19     h.merge( h1 );
20     h2 = h;
21 
22     for( i = 1; i < numItems; ++i )
23     {
24         int x;
25         h2.deleteMin( x );
26         if( x != i )
27             cout << "Oops! " << i << endl;
28     }
29 
30     if( !h1.isEmpty( ) )
31         cout << "Oops! h1 should have been empty!" << endl;
32 
33     cout << "End test... no other output is good" << endl;
34 
35     return 0;
36 }

 

【数据结构】左式堆,布布扣,bubuko.com

【数据结构】左式堆

标签:style   blog   color   os   strong   io   数据   for   

原文地址:http://www.cnblogs.com/dracohan/p/3879849.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!