BWAPI
|
00001 #pragma once 00002 00003 #include <vector> 00004 #include <map> 00005 #include <utility> 00006 00013 template <class _Tp,class _Val> 00014 class Heap 00015 { 00016 private : 00018 std::vector< std::pair< _Tp, _Val > > data; 00019 00021 std::map< _Tp, int> mapping; 00022 00024 bool minHeap; 00025 00031 int percolate_up(int index); 00032 00038 int percolate_down(int index); 00039 00040 public : 00041 Heap(bool isMinHeap = false) : minHeap(isMinHeap) {} 00042 ~Heap() {} 00047 void push(std::pair< _Tp, _Val > x); 00051 void pop(); 00055 const std::pair< _Tp, _Val >& top() const; 00063 bool set(_Tp& x,_Val& v); 00069 const _Val& get(_Tp& x) const; 00070 00074 bool contains(_Tp& x) const; 00075 00079 bool empty() const; 00083 int size() const; 00087 void clear(); 00093 bool erase(_Tp& x); 00094 }; 00095 00096 //------------------------------- PERCOLATE UP --------------------------------- 00097 template <class _Tp, class _Val> 00098 int Heap<_Tp,_Val>::percolate_up(int index) 00099 { 00100 if (index<0 || index>=(int)data.size()) 00101 return -1; 00102 unsigned int parent=(index-1)/2; 00103 int m=1; 00104 if (this->minHeap) m=-1; 00105 while(index>0 && m*data[parent].second<m*data[index].second) 00106 { 00107 std::pair<_Tp,_Val> temp=data[parent]; 00108 data[parent]=data[index]; 00109 data[index]=temp; 00110 (*mapping.find(data[index].first)).second=index; 00111 index=parent; 00112 parent=(index-1)/2; 00113 } 00114 (*mapping.find(data[index].first)).second=index; 00115 return index; 00116 } 00117 00118 //------------------------------ PERCOLATE DOWN -------------------------------- 00119 template <class _Tp, class _Val> 00120 int Heap<_Tp,_Val>::percolate_down(int index) 00121 { 00122 if (index<0 || index>=(int)data.size()) 00123 return -1; 00124 unsigned int lchild=index*2+1; 00125 unsigned int rchild=index*2+2; 00126 unsigned int mchild; 00127 int m=1; 00128 if (this->minHeap) m=-1; 00129 while((data.size()>lchild && m*data[index].second<m*data[lchild].second) || 00130 (data.size()>rchild && m*data[index].second<m*data[rchild].second)) 00131 { 00132 mchild=lchild; 00133 if (data.size()>rchild && m*data[rchild].second>m*data[lchild].second) 00134 mchild=rchild; 00135 std::pair< _Tp, _Val > temp=data[mchild]; 00136 data[mchild]=data[index]; 00137 data[index]=temp; 00138 (*mapping.find(data[index].first)).second=index; 00139 index=mchild; 00140 lchild=index*2+1; 00141 rchild=index*2+2; 00142 } 00143 (*mapping.find(data[index].first)).second=index; 00144 return index; 00145 } 00146 //----------------------------------- PUSH ------------------------------------- 00147 template <class _Tp, class _Val> 00148 void Heap<_Tp,_Val>::push(std::pair< _Tp, _Val > x) 00149 { 00150 int index=data.size(); 00151 if (mapping.insert(std::make_pair(x.first,index)).second) 00152 { 00153 data.push_back(x); 00154 percolate_up(index); 00155 } 00156 } 00157 00158 //----------------------------------- POP -------------------------------------- 00159 template <class _Tp, class _Val> 00160 void Heap<_Tp,_Val>::pop() 00161 { 00162 if (data.empty()) 00163 return; 00164 mapping.erase(data.front().first); 00165 data.front()=data.back(); 00166 data.pop_back(); 00167 if (data.empty()) 00168 return; 00169 std::map<_Tp,int>::iterator iter=mapping.find(data.front().first); 00170 if (iter!=mapping.end()) 00171 { 00172 (*iter).second=0; 00173 percolate_down(0); 00174 } 00175 } 00176 00177 //----------------------------------- TOP -------------------------------------- 00178 template <class _Tp, class _Val> 00179 const std::pair< _Tp, _Val >& Heap<_Tp,_Val>::top() const 00180 { 00181 return data.front(); 00182 } 00183 00184 //---------------------------------- EMPTY ------------------------------------- 00185 template <class _Tp, class _Val> 00186 bool Heap<_Tp,_Val>::empty() const 00187 { 00188 return data.empty(); 00189 } 00190 00191 //----------------------------------- SET -------------------------------------- 00192 template <class _Tp, class _Val> 00193 bool Heap<_Tp,_Val>::set(_Tp& x,_Val& v) 00194 { 00195 std::map<_Tp,int>::iterator iter=mapping.find(x); 00196 if (iter==mapping.end()) 00197 { 00198 push(std::make_pair(x,v)); 00199 return true; 00200 } 00201 int index=(*iter).second; 00202 data[index].second=v; 00203 index=percolate_up(index); 00204 if (index>=0 && index<(int)data.size()) 00205 { 00206 percolate_down(index); 00207 return true; 00208 } 00209 return false; 00210 } 00211 00212 //----------------------------------- GET -------------------------------------- 00213 template <class _Tp, class _Val> 00214 const _Val& Heap<_Tp,_Val>::get(_Tp& x) const 00215 { 00216 std::map<_Tp,int>::const_iterator iter=mapping.find(x); 00217 int index=(*iter).second; 00218 return data[index].second; 00219 } 00220 00221 //--------------------------------- CONTAINS ----------------------------------- 00222 template <class _Tp, class _Val> 00223 bool Heap<_Tp,_Val>::contains(_Tp& x) const 00224 { 00225 std::map<_Tp,int>::const_iterator iter=mapping.find(x); 00226 return (iter!=mapping.end()); 00227 } 00228 00229 //---------------------------------- SIZE -------------------------------------- 00230 template <class _Tp, class _Val> 00231 int Heap<_Tp,_Val>::size() const 00232 { 00233 return data.size(); 00234 } 00235 00236 //---------------------------------- CLEAR ------------------------------------- 00237 template <class _Tp, class _Val> 00238 void Heap<_Tp,_Val>::clear() 00239 { 00240 data.clear(); 00241 mapping.clear(); 00242 } 00243 00244 //---------------------------------- ERASE ------------------------------------- 00245 template <class _Tp, class _Val> 00246 bool Heap<_Tp,_Val>::erase(_Tp& x) 00247 { 00248 std::map<_Tp,int>::iterator iter=mapping.find(x); 00249 if (iter==mapping.end()) 00250 return false; 00251 if (data.size()==1) 00252 this->clear(); 00253 else 00254 { 00255 int index=(*iter).second; 00256 data[index]=data.back(); 00257 data.pop_back(); 00258 mapping.erase(iter); 00259 percolate_down(index); 00260 } 00261 return true; 00262 } 00263 //------------------------------------------------------------------------------