【数据结构】堆 Heap

堆(Heap)的C++实现

  1 #include <iostream> 
  2 using namespace std;
  3 
  4 template <class T> 
  5 class Heap
  6 {                       
  7 private:
  8     // hlist points at the array which can be allocated by
  9     // the constructor (inArray == 0) or passed as a
 10     // parameter (inArray == 1)         
 11     T *hlist;
 12     int inArray;
 13 
 14     // max number allowed and current size of heap
 15     int maxheapsize;        
 16     int heapsize;                // identifies end of list
 17 
 18     // error message utility function 
 19     void error(char errmsg[]);
 20 
 21     // utility functions for Delete/Insert to restore heap
 22     void FilterDown(int i);
 23     void FilterUp(int i);
 24 public:
 25     // constructors/destructor
 26     Heap(int maxsize);           // create empty heap
 27     Heap(T arr[],int n);         // "heapify" arr
 28     Heap(const Heap<T>& H);      // copy constructor
 29     ~Heap(void);                 // destructor
 30 
 31     // overloaded operators: "=", "[]", "T*"
 32     Heap<T>& operator= (const Heap<T>& rhs);
 33     const T& operator[](int i);
 34 
 35     // list methods       
 36     int ListSize(voidconst;
 37     int ListEmpty(voidconst;
 38     int ListFull(voidconst;
 39     void Insert(const T& item);
 40     T Delete(void);
 41     void ClearList(void);
 42 
 43     void show()
 44     {
 45         for(int i=0;i<heapsize;i++)
 46             cout << hlist[i] << " ";
 47         cout << endl;
 48     }
 49 };
 50 
 51 // print error message and terminate the program 
 52 template <class T>
 53 void Heap<T>::error(char errmsg[])
 54 {
 55     cerr <<  errmsg << endl;
 56     exit(1);
 57 }
 58 
 59 // utility to restore the heap; starting at index i,
 60 // exchange parent and child so that subtree from i is a heap
 61 template <class T>
 62 void Heap<T>::FilterDown (int i)
 63 {
 64     int currentpos, childpos;
 65     T target;
 66 
 67     // start at i and set its value as the target   
 68     currentpos = i;         
 69     target = hlist[i];
 70 
 71     // compute the left child index and begin a scan down
 72     // path of children, stopping at end of list (heapsize)
 73     childpos = 2 * i + 1;         
 74     while (childpos < heapsize)         // check for end of list
 75     {
 76         // Index of right child is childpos+1. Set childpos to
 77         // index of the smaller of the two children
 78         if ((childpos+1 < heapsize) && 
 79             (hlist[childpos+1] <= hlist[childpos]))
 80             childpos = childpos + 1;
 81 
 82         // parent is less than children, heap ok. quit
 83         if (target <= hlist[childpos])
 84             break
 85         else 
 86         {
 87             // move value of smaller child to the parent;
 88             // position of smaller child is now vacated  
 89             hlist[currentpos] = hlist[childpos];
 90 
 91             // update indices to continue the scan          
 92             currentpos = childpos;
 93             childpos = 2 * currentpos + 1;
 94         } 
 95     }
 96     // assign target to the most recently vacated position
 97     hlist[currentpos] = target;
 98 }
 99 
100 // utility to restore the heap; starting at index i,
101 // move up tree from parent to parent. exchange elements if
102 // the child has a value less than the parent
103 template <class T>
104 void Heap<T>::FilterUp (int i)
105 {
106     int currentpos, parentpos;
107     T target;
108 
109     // currentpos is an index that traverses path of parents.
110     // target is value hlist[i] and is repositioned in path
111     currentpos = i;
112     parentpos = (i-1)/2;
113     target = hlist[i];
114 
115     // traverse path of parents up to the root 
116     while (currentpos != 0)
117     {
118         // if parent <= target, heap condition is ok. break!
119         if (hlist[parentpos] <= target)
120             break
121         else 
122             // move child value to parent and update indices to 
123             // look at the next parent. 
124         {
125             // move data from parent position to current
126             // position. update current position to parent
127             // position. compute next parent
128             hlist[currentpos] = hlist[parentpos];
129             currentpos = parentpos;
130             parentpos = (currentpos-1)/2;
131         } 
132     }
133     // the correct location has been discovered. assign target
134     hlist[currentpos] = target;
135 }
136 
137 template <class T>
138 Heap<T>::Heap(int size)
139 {  
140     if (size <= 0
141         error("Bad list size.");
142     hlist = new T[size];
143     if (hlist == 0)
144         error("Memory allocation failure."); 
145     maxheapsize = size;
146     heapsize = 0;
147     inArray = 0;
148 }
149 
150 // constructor to convert an array to a heap.
151 // the array and its size are passed as parameters
152 template <class T>
153 Heap<T>::Heap(T arr[],int n)
154 {
155     int currentpos;
156 
157     // n <= 0 is invalid array size; terminate program
158     if (n <= 0
159         error("Bad list size.");
160 
161     // use n to set heap size and maximum heap size; assign
162     // the arrary arr to the heap list     
163     maxheapsize = n;
164     heapsize = n ; 
165     hlist = new T[n];
166     memcpy(hlist,arr,sizeof(T)*n);
167 
168     // set currentpos to last parent index; call FilterDown
169     // in a loop with index in the range currentpos down to 0;
170     currentpos = (heapsize - 2)/2;
171     while(currentpos >= 0)
172     { 
173         // establish heap condition for subtree with root
174         // hlist[currentpos]
175         FilterDown(currentpos);
176         currentpos--;
177     }
178     // set inArray to True so Heap will not deallocate array
179     inArray = 1;
180 }
181 
182 template <class T>
183 Heap<T>::Heap(const Heap<T>& A)
184 {
185     int n = A.heapsize;
186 
187     heapsize = n;                          
188     maxheapsize = A.maxheapsize;
189     hlist = new T[maxheapsize];                     
190     if (hlist == 0)
191         error("Memory allocation failure."); 
192     while (n--) 
193         hlist[n] = A.hlist[n];                 
194     inArray = 0;   // always build new heap in dynamic memory
195 }
196 
197 template <class T>
198 Heap<T>::~Heap(void)
199 { 
200     if (!inArray)  // don't delete hlist unless allocated.
201         delete[] hlist;
202 }
203 
204 template <class T>                              
205 Heap<T>& Heap<T>::operator=(const Heap<T>& rhs)
206 {
207     int n = rhs.heapsize;
208 
209     heapsize = n;        
210     if (maxheapsize != rhs.maxheapsize || inArray)
211     {
212         maxheapsize = rhs.maxheapsize;
213         // destroy the heap if not allocated in static array
214         if (!inArray)
215             delete [] hlist;
216         hlist = new T[maxheapsize]; // allocate a new array
217         if (hlist == NULL)
218             error("Memory allocation failure.");
219     }
220     while (n--)  // do item by item copy 
221         hlist[n] = rhs.hlist[n];
222     inArray = 0// assignment puts heap in dynamic memory
223     return *this;
224 }
225 
226 template <class T>
227 int Heap<T>::ListSize(voidconst
228 { 
229     return heapsize; 
230 }
231 
232 template <class T>
233 int Heap<T>::ListEmpty(voidconst
234 {
235     return heapsize == 0;
236 }
237 
238 template <class T>
239 int Heap<T>::ListFull(voidconst
240 {
241     return heapsize == maxheapsize;
242 }
243 
244 template <class T>
245 const T& Heap<T>::operator[](int i)
246 {  
247     if (i < 0 || i >= heapsize)
248         error("Heap index out of range: ");
249     return hlist[i];
250 }
251 
252 // insert a new item in the heap and update the structure
253 template <class T>
254 void Heap<T>::Insert(const T& item)
255 {
256     // check for a full heap and terminate if True
257     if (heapsize == maxheapsize)
258         error("Heap full");
259     // store the item at the end of the heap and increment 
260     // heapsize;   call FilterUp to restore the heap condition
261     hlist[heapsize] = item; 
262     FilterUp(heapsize);
263     heapsize++;
264 }
265 
266 // return the value of the first element and update the heap
267 // a deletion with an empty heap creates an error message and 
268 // terminates the program
269 template <class T>
270 T Heap<T>::Delete(void)
271 {
272     T tempitem;
273 
274     // check for an empty heap
275     if (heapsize == 0)
276         error("Heap empty"); 
277 
278     // copy the root to tempitem; replace the root with the last
279     // value in the heap and decrement the heap size
280     tempitem = hlist[0];
281     hlist[0] = hlist[heapsize-1]; 
282     heapsize--;
283 
284     // call FilterDown to position the new root value in heap
285     FilterDown(0);
286 
287     // return the original root value
288     return tempitem;
289 }
290 
291 template <class T>
292 void Heap<T>::ClearList(void)
293 {
294     heapsize = 0;
295 }
296  
297 
298 int main()
299 {
300     
301     int x[] = {23,21,4,5,6,7};
302     Heap<int> h(x,6);
303     h.show(); 
304 
305     system("pause");
306     return 0;
307 }

 

 

 

posted @ 2012-07-14 21:34  Keosu  阅读(2174)  评论(0编辑  收藏  举报