|
BWAPI
|
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 };
1.7.6.1