BWAPI
Skynet/Skynet/Heap.h
Go to the documentation of this file.
00001 #pragma once
00002 
00003 #include <vector>
00004 
00005 template <class Key, class Val>
00006 class Heap
00007 {
00008 public:
00009         Heap(bool isMinHeap = false) : mIsMinHeap(isMinHeap) {}
00010 
00011         void push(const std::pair<Key, Val> &val)
00012         {
00013                 int index = mData.size();
00014                 if(mMapping.insert(std::make_pair(val.first, index)).second)
00015                 {
00016                         mData.push_back(val);
00017                         percolate_up(index);
00018                 }
00019         }
00020 
00021         void pop()
00022         {
00023                 if(mData.empty())
00024                         return;
00025 
00026                 mMapping.erase(mData.front().first);
00027                 mData.front() = mData.back();
00028                 mData.pop_back();
00029 
00030                 if(mData.empty())
00031                         return;
00032 
00033                 std::map<Key, int>::iterator it = mMapping.find(mData.front().first);
00034                 if(it != mMapping.end())
00035                 {
00036                         it->second = 0;
00037                         percolate_down(0);
00038                 }
00039         }
00040 
00041         const std::pair<Key, Val> &top() const
00042         {
00043                 return mData.front();
00044         }
00045 
00046         bool empty() const
00047         {
00048                 return mData.empty();
00049         }
00050 
00051         bool set(const Key &key, const Val &val)
00052         {
00053                 std::map<Key, int>::iterator it = mMapping.find(key);
00054                 if(it == mMapping.end())
00055                 {
00056                         push(std::make_pair(key, val));
00057                         return true;
00058                 }
00059 
00060                 int index = it->second;
00061                 mData[index].second = val;
00062                 index = percolate_up(index);
00063 
00064                 if(index >= 0 && index < (int)mData.size())
00065                 {
00066                         percolate_down(index);
00067                         return true;
00068                 }
00069 
00070                 return false;
00071         }
00072 
00073         const Val &get(const Key &key) const
00074         {
00075                 std::map<Key, int>::const_iterator it = mMapping.find(key);
00076                 int index = it->second;
00077                 return mData[index].second;
00078         }
00079 
00080         bool contains(const Key &key) const
00081         {
00082                 std::map<Key, int>::const_iterator it = mMapping.find(key);
00083                 return (it != mMapping.end());
00084         }
00085 
00086         int size() const
00087         {
00088                 return mData.size();
00089         }
00090 
00091         void clear()
00092         {
00093                 mData.clear();
00094                 mMapping.clear();
00095         }
00096 
00097         bool erase(const Key &key)
00098         {
00099                 std::map<Key, int>::iterator it = mMapping.find(key);
00100                 if(it == mMapping.end())
00101                         return false;
00102 
00103                 if(mData.size() == 1)
00104                         clear();
00105                 else
00106                 {
00107                         int index = it->second;
00108                         mData[index] = mData.back();
00109                         mData.pop_back();
00110                         mMapping.erase(it);
00111                         percolate_down(index);
00112                 }
00113 
00114                 return true;
00115         }
00116 
00117 private:
00118         std::vector<std::pair<Key, Val>> mData;
00119         std::map<Key, int> mMapping;
00120         bool mIsMinHeap;
00121 
00122         int percolate_up(int index)
00123         {
00124                 if(index < 0 || index >= (int)mData.size())
00125                         return -1;
00126 
00127                 unsigned int parent = (index - 1) / 2;
00128                 int m = mIsMinHeap ? -1 : 1;
00129 
00130                 while(index > 0 && m * mData[parent].second < m * mData[index].second)
00131                 {
00132                         std::swap(mData[parent], mData[index]);
00133                         mMapping.find(mData[index].first)->second = index;
00134                         index = parent;
00135                         parent = (index - 1) / 2;
00136                 }
00137                 mMapping.find(mData[index].first)->second = index;
00138 
00139                 return index;
00140         }
00141 
00142         int percolate_down(int index)
00143         {
00144                 if(index < 0 || index >= (int)mData.size())
00145                         return -1;
00146 
00147                 unsigned int lchild = index * 2 + 1;
00148                 unsigned int rchild = index * 2 + 2;
00149                 unsigned int mchild;
00150                 int m = mIsMinHeap ? -1 : 1;
00151 
00152                 while((mData.size() > lchild && m * mData[index].second < m * mData[lchild].second) || (mData.size() > rchild && m * mData[index].second < m * mData[rchild].second))
00153                 {
00154                         mchild = lchild;
00155                         if(mData.size() > rchild && m * mData[rchild].second > m * mData[lchild].second)
00156                                 mchild = rchild;
00157 
00158                         std::swap(mData[mchild], mData[index]);
00159                         mMapping.find(mData[index].first)->second = index;
00160                         index = mchild;
00161                         lchild = index * 2 + 1;
00162                         rchild = index * 2 + 2;
00163                 }
00164 
00165                 mMapping.find(mData[index].first)->second = index;
00166 
00167                 return index;
00168         }
00169 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines