BWAPI
SnippyHolloW-BroodwarBotQ-f01ab56/src/Macro/Heap.h
Go to the documentation of this file.
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   //------------------------------------------------------------------------------
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines