Planeshift
|
00001 /* 00002 * heap.h 00003 * 00004 * Copyright (C) 2005 Atomic Blue ([email protected], http://www.planeshift.it) 00005 * 00006 * Credits : Andrew Dai 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU General Public License 00010 * as published by the Free Software Foundation (version 2 00011 * of the License). 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 * 00020 * Creation Date: 10/Feb 2005 00021 * Description : This is an implementation of a min heap. (a priority queue) 00022 * 00023 */ 00024 00025 #ifndef __HEAP_H__ 00026 #define __HEAP_H__ 00027 00028 #include <csutil/array.h> 00029 00034 template <class T> 00035 class Heap : protected csArray<T*> 00036 { 00037 // Work around gcc 3.4 braindamage. 00038 using csArray<T*>::Get; 00039 using csArray<T*>::Top; 00040 00041 public: 00042 Heap(int ilimit = 0) 00043 : csArray<T*>(ilimit) 00044 { 00045 } 00046 00047 size_t Length () const 00048 { 00049 return csArray<T*>::GetSize(); 00050 } 00051 00052 void Insert(T* what) 00053 { 00054 size_t i; 00055 00056 // Make room for new element 00057 this->SetSize(Length() + 1); 00058 00059 // This special case is required as we are not using a sentinel 00060 if(Length() > 1) 00061 for( i = Length()-1; i != 0 && *Get((i-1)/2) > *what; i = (i-1)/2) 00062 this->Put(i, this->Get((i-1)/2)); 00063 else 00064 i = 0; 00065 00066 this->Put(i, what); 00067 } 00068 00069 T* DeleteMin() 00070 { 00071 size_t i, child; 00072 T* minElement = this->Get(0); 00073 T* lastElement = this->Top(); 00074 00075 CS_ASSERT(Length()); 00076 // Shrink the array by 1 00077 this->Truncate(Length() - 1); 00078 00079 if(!Length()) 00080 return minElement; 00081 00082 for(i = 0; i * 2 + 1 < Length(); i = child) 00083 { 00084 // Find the smaller child 00085 child = i * 2 + 1; 00086 if( child != Length()-1 && *this->Get(child + 1) < *this->Get(child) ) 00087 child++; 00088 00089 // Move it down one level 00090 if( *lastElement > *this->Get(child)) 00091 this->Put(i, this->Get(child)); 00092 else 00093 break; 00094 } 00095 this->Put(i, lastElement); 00096 return minElement; 00097 } 00098 00099 T* FindMin() 00100 { 00101 if(Length()) 00102 return this->Get(0); 00103 else 00104 return NULL; 00105 } 00106 }; 00107 00110 #endif 00111