heap.h
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00038 #ifndef COLLECTIONS_HEAP_H
00039 #define COLLECTIONS_HEAP_H
00040 
00041 #include "fastlib/col/arraylist.h"
00042 
00043 
00052 template <typename TKey, typename TValue = Empty>
00053 class MinHeap {
00054   
00055 
00056  public:
00057   typedef TKey Key;
00058   typedef TValue Value;
00059 
00060  private:
00061   struct Entry {
00062     TKey key;
00063     TValue value;
00064 
00065     OBJECT_TRAVERSAL_SHALLOW(Entry) {
00066       OT_OBJ(key);
00067       OT_OBJ(value);
00068     }
00069   };
00070 
00071   ArrayList<Entry> entries_;
00072 
00073   OBJECT_TRAVERSAL(MinHeap) {
00074     OT_OBJ(entries_);
00075   }
00076 
00077  public:
00081   void Init() {
00082     entries_.Init();
00083   }
00084 
00088   bool is_empty() const {
00089     return entries_.size() == 0;
00090   }
00091 
00098   void Put(Key key, Value value) {
00099     Entry entry;
00100 
00101     entries_.PushBack();
00102 
00103     entry.key = key;
00104     entry.value = value;
00105 
00106     WalkUp_(entry, entries_.size() - 1);
00107   }
00108 
00114   Value Pop() {
00115     Value t = entries_[0].value;
00116 
00117     PopOnly();
00118 
00119     return t;
00120   }
00121 
00128   void PopOnly() {
00129     Entry entry;
00130     entries_.PopBackInit(&entry);
00131 
00132     if (likely(entries_.size() != 0)) {
00133       WalkDown_(entry, 0);
00134     }
00135   }
00136 
00140   Value top() const {
00141     return entries_[0].value;
00142   }
00143 
00147   Key top_key() const {
00148     return entries_[0].key;
00149   }
00150   
00154   void set_top(Value v) {
00155     entries_[0].value = v;
00156   }
00157 
00161   index_t size() const {
00162     return entries_.size();
00163   }
00164 
00165  private:
00166   static index_t ChildIndex_(index_t i) {
00167     return (i << 1) + 1;
00168   }
00169 
00170   static index_t ParentIndex_(index_t i) {
00171     return (i - 1) >> 1;
00172   }
00173 
00174   index_t WalkDown_(const Entry& entry, index_t i) {
00175     Key key = entry.key;
00176     Entry *entries = entries_.begin();
00177     index_t last = entries_.size() - 1;
00178 
00179     for (;;) {
00180       index_t c = ChildIndex_(i);
00181 
00182       if (unlikely(c > last)) {
00183         break;
00184       }
00185 
00186       
00187       if (likely(c != last)) {
00188         c += entries[c + 1].key < entries[c].key ? 1 : 0;
00189       }
00190 
00191       if (key <= entries[c].key) {
00192         break;
00193       }
00194 
00195       entries[i] = entries[c];
00196       i = c;
00197     }
00198 
00199     entries[i] = entry;
00200 
00201     return i;
00202   }
00203 
00204   index_t WalkUp_(const Entry& entry, index_t i) {
00205     Key key = entry.key;
00206     Entry *entries = entries_.begin();
00207 
00208     for (;;) {
00209       index_t p;
00210 
00211       if (unlikely(i == 0)) {
00212         break; 
00213       }
00214 
00215       p = ParentIndex_(i);
00216 
00217       if (key >= entries[p].key) {
00218         break;
00219       }
00220 
00221       entries[i] = entries[p];
00222 
00223       i = p;
00224     }
00225 
00226     entries[i] = entry;
00227 
00228     return i;
00229   }
00230 };
00231 
00232 #endif