PriorityQueue.inl
Go to the documentation of this file.00001 //*** PriorityQueue.inl *** 00002 00003 #include "Debug.h" 00004 #include "StandardLibrary.h" 00005 00006 //*** Constructor *** 00007 00008 template <class TYPE> 00009 PriorityQueue<TYPE>::PriorityQueue(CompareFunction compareFunction, int initialCapacity): 00010 compareFunction_(compareFunction), 00011 initialCapacity_(initialCapacity), 00012 capacity_(initialCapacity), 00013 itemCount_(0), 00014 items_(0) { 00015 } 00016 00017 00018 //*** Copy Constructor *** 00019 00020 template <class TYPE> 00021 PriorityQueue<TYPE>::PriorityQueue(const PriorityQueue<TYPE>& priorityQueueToCopy ): 00022 compareFunction_(priorityQueueToCopy.compareFunction_), 00023 initialCapacity_(priorityQueueToCopy.initialCapacity_), 00024 capacity_(priorityQueueToCopy.capacity_), 00025 itemCount_(priorityQueueToCopy.itemCount_), 00026 items_(0) 00027 { 00028 if (!priorityQueueToCopy.items_) 00029 { 00030 return; 00031 } 00032 00033 items_=new TYPE[capacity_]; 00034 00035 Assert(items_,"Couldn't allocate memory for priority queue"); 00036 if (!items_) 00037 { 00038 FatalError("Allocation failed when allocating memory for priority queue"); 00039 } 00040 00041 // Copy each item of the other array 00042 for (int i=0; i<itemCount_; i++) 00043 { 00044 items_[i]=priorityQueueToCopy.items_[i]; 00045 } 00046 } 00047 00048 //*** Assignment operator *** 00049 00050 00051 template <class TYPE> 00052 const PriorityQueue<TYPE>& PriorityQueue<TYPE>::operator =(const PriorityQueue<TYPE>& priorityQueueToCopy) 00053 { 00054 if (items_) 00055 { 00056 delete[] items_; 00057 items_=0; 00058 } 00059 00060 compareFunction_=priorityQueueToCopy.compareFunction_; 00061 initialCapacity_=priorityQueueToCopy.initialCapacity_; 00062 capacity_=priorityQueueToCopy.capacity_; 00063 itemCount_=priorityQueueToCopy.itemCount_; 00064 00065 if (priorityQueueToCopy.items_) 00066 { 00067 items_=new TYPE[capacity_]; 00068 00069 Assert(items_,"Couldn't allocate memory for priority queue"); 00070 if (!items_) 00071 { 00072 FatalError("Allocation failed when allocating memory for priority queue"); 00073 } 00074 00075 // Copy each item of the other array 00076 for (int i=0; i<itemCount_; i++) 00077 { 00078 items_[i]=priorityQueueToCopy.items_[i]; 00079 } 00080 } 00081 00082 return *this; 00083 } 00084 00085 00086 00087 //*** Destructor *** 00088 00089 template <class TYPE> 00090 PriorityQueue<TYPE>::~PriorityQueue() 00091 { 00092 // Free memory used by the array 00093 if (items_) 00094 { 00095 delete[] items_; 00096 items_=0; 00097 } 00098 } 00099 00100 //*** Add *** 00101 00102 template <class TYPE> 00103 TYPE& PriorityQueue<TYPE>::Add(const TYPE& item) 00104 { 00105 // Check if the array is full 00106 if (!items_ || itemCount_>=capacity_) 00107 { 00108 int newCapacity=capacity_; 00109 if (itemCount_>=capacity_) 00110 { 00111 newCapacity*=2; 00112 } 00113 // Create a new array with twice the size 00114 TYPE* newItems=new TYPE[newCapacity]; 00115 Assert(newItems,"Couldn't allocate memory for dynamic array"); 00116 if (!newItems) 00117 { 00118 FatalError("Allocation failed when allocating memory for priority queue"); 00119 } 00120 00121 // Copy each item from the old array to the new one 00122 for (int i=0; i<itemCount_; i++) 00123 { 00124 newItems[i]=items_[i]; 00125 } 00126 00127 // Delete the old array 00128 if (items_) 00129 { 00130 delete[] items_; 00131 items_=0; 00132 } 00133 00134 // Store the pointer to the new array instead of the old 00135 items_=newItems; 00136 00137 // Increase the maximum number of items 00138 capacity_=newCapacity; 00139 } 00140 00141 // Set the item 00142 items_[itemCount_]=item; 00143 itemCount_++; 00144 00145 00146 // "Bubble" the item to the right position in the tree 00147 int index=itemCount_; 00148 while (index>1 && compareFunction_(items_[index-1],items_[index/2-1])) 00149 { 00150 // Swap items 00151 TYPE temp=items_[index/2-1]; 00152 items_[index/2-1]=items_[index-1]; 00153 items_[index-1]=temp; 00154 00155 index=index/2; 00156 } 00157 00158 return items_[index-1]; 00159 } 00160 00161 00162 //*** Remove *** 00163 00164 template <class TYPE> 00165 TYPE PriorityQueue<TYPE>::Remove() 00166 { 00167 if (itemCount_==0) 00168 { 00169 return TYPE(); 00170 } 00171 00172 TYPE returnValue=items_[0]; 00173 items_[0]=items_[itemCount_-1]; 00174 itemCount_--; 00175 00176 if (itemCount_==0) 00177 { 00178 return returnValue; 00179 } 00180 00181 int v=1; 00182 int u=0; 00183 while (u!=v) 00184 { 00185 u=v; 00186 // If both children exist 00187 if ((2*u+1)<=itemCount_) 00188 { 00189 // Select the lowest of the two children. 00190 if (!compareFunction_(items_[u-1],items_[2*u -1])) 00191 { 00192 v=2*u; 00193 } 00194 if (!compareFunction_(items_[v-1],items_[2*u+1 -1])) 00195 { 00196 v=2*u+1; 00197 } 00198 } 00199 00200 // If only child #1 exists 00201 else if (2*u<=itemCount_) 00202 { 00203 // Check if the cost is greater than the child 00204 if (!compareFunction_(items_[u-1],items_[2*u-1])) 00205 { 00206 v=2*u; 00207 } 00208 } 00209 00210 if (u!=v) 00211 { 00212 // Swap items 00213 TYPE temp=items_[u-1]; 00214 items_[u-1]=items_[v-1]; 00215 items_[v-1]=temp; 00216 } 00217 } 00218 00219 return returnValue; 00220 } 00221 00222 00223 //*** Update *** 00224 00225 template <class TYPE> 00226 void PriorityQueue<TYPE>::Update(int index) 00227 { 00228 while (index>1 && compareFunction_(items_[index-1],items_[index/2-1])) 00229 { 00230 // Swap items 00231 TYPE temp=items_[index/2-1]; 00232 items_[index/2-1]=items_[index-1]; 00233 items_[index-1]=temp; 00234 00235 index=index/2; 00236 } 00237 } 00238 00239 00240 //*** Clear *** 00241 00242 template <class TYPE> 00243 void PriorityQueue<TYPE>::Clear(bool releaseMemory) 00244 { 00245 // Clear used range 00246 itemCount_=0; 00247 00248 // Free allocated memory if requested 00249 if (releaseMemory) 00250 { 00251 // Free the memory 00252 if (items_) 00253 { 00254 delete[] items_; 00255 items_=0; 00256 } 00257 00258 // Reset to initial size 00259 capacity_=initialCapacity_; 00260 } 00261 } 00262 00263 00264 //*** ItemExists *** 00265 00266 template <class TYPE> 00267 bool PriorityQueue<TYPE>::ItemExists(const TYPE& item) const 00268 { 00269 for (int i=0; i<itemCount_; i++) 00270 { 00271 if (items_[i]==item) 00272 { 00273 return true; 00274 } 00275 } 00276 00277 return false; 00278 } 00279 00280 00281 //*** GetItemCount *** 00282 00283 template <class TYPE> 00284 int PriorityQueue<TYPE>::GetItemCount() const 00285 { 00286 return itemCount_; 00287 } 00288 00289 00290 //*** Get *** 00291 00292 template <class TYPE> 00293 TYPE& PriorityQueue<TYPE>::Get(int index) const 00294 { 00295 return items_[index]; 00296 } 00297 00298 00299 //*** GetCapacity *** 00300 00301 template <class TYPE> 00302 int PriorityQueue<TYPE>::GetCapacity() const 00303 { 00304 return capacity_; 00305 } 00306 00307 00308 //*** SetCapacity *** 00309 00310 template <class TYPE> 00311 void PriorityQueue<TYPE>::SetCapacity(int capacity) 00312 { 00313 if (itemCount_>capacity) 00314 { 00315 itemCount_=capacity; 00316 } 00317 00318 if (items_) 00319 { 00320 // Create a new array with the new size 00321 TYPE* newItems=new TYPE[capacity]; 00322 Assert(newItems,"Couldn't allocate memory for dynamic array"); 00323 if (!newItems) 00324 { 00325 FatalError("Allocation failed when allocating memory for priority queue"); 00326 } 00327 00328 // Copy each item from the old array to the new one 00329 for (int i=0; i<itemCount_; i++) 00330 { 00331 newItems[i]=items_[i]; 00332 } 00333 00334 // Delete the old array 00335 delete[] items_; 00336 00337 // Store pointer to the new array 00338 items_=newItems; 00339 } 00340 00341 00342 // Store the new value for maximum number of items 00343 capacity_=capacity; 00344 }
Reproduction/republishing of any material on this site without permission is strictly prohibited.
