Index: src/include/bin_heap.hh
===================================================================
--- src/include/bin_heap.hh	(revision 37)
+++ src/include/bin_heap.hh	(revision 37)
@@ -0,0 +1,159 @@
+#ifndef BIN_HEAP_HH
+#define BIN_HEAP_HH
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace marci {
+
+  template <typename Key, typename Val, typename KeyIntMap,
+	    typename Compare = std::less<Val> >
+  class BinHeap {
+
+  public:
+    typedef Key	             KeyType;
+    // FIXME: stl-ben nem ezt hivjak value_type -nak, hanem a kovetkezot...
+    typedef Val              ValueType;
+    typedef std::pair<KeyType,ValueType>     PairType;
+    typedef KeyIntMap        KeyIntMapType;
+    typedef Compare          ValueCompare;
+
+    /**
+     * Each Key element have a state associated to it. It may be "in heap",
+     * "pre heap" or "post heap". The later two are indifferent from the
+     * heap's point of view, but may be useful to the user.
+     *
+     * The KeyIntMap _should_ be initialized in such way, that it maps
+     * PRE_HEAP (-1) to any element to be put in the heap...
+     */
+
+    enum state {
+      IN_HEAP = 0,
+      PRE_HEAP = -1,
+      POST_HEAP = -2
+    };
+
+  private:
+    std::vector<PairType> data;
+    Compare comp;
+    // FIXME: jo ez igy???
+    KeyIntMap &kim;
+
+  public:
+    BinHeap(KeyIntMap &_kim) : kim(_kim) {}
+    BinHeap(KeyIntMap &_kim, const Compare &_comp) : comp(_comp), kim(_kim) {}
+
+
+    int size() const { return data.size(); }
+    bool empty() const { return size() == 0; }
+
+  private:
+    static int parent(int i) { return (i-1)/2; }
+    static int second_child(int i) { return 2*i+2; }
+    bool less(const PairType &p1, const PairType &p2) {
+      return comp(p1.second, p2.second);
+    }
+
+    int bubble_up(int hole, PairType p);
+    int bubble_down(int hole, PairType p, int length);
+
+    void move(const PairType &p, int i) {
+      data[i] = p;
+      kim.put(p.first, i);
+    }
+
+  public:
+    void push(const PairType &p) {
+      int n = data.size();
+      data.resize(n+1);
+      bubble_up(n, p);
+    }
+    void push(const Key &k, const Val &v) { push(PairType(k,v)); }
+
+    Key top() const {
+      // FIXME: test size>0 ?
+      return data[0].first;
+    }
+    Val topValue() const {
+      // FIXME: test size>0 ?
+      return data[0].second;
+    }
+
+    void pop() {
+      int n = data.size()-1;
+      if ( n>0 ) {
+	bubble_down(0, data[n], n);
+      }
+      if ( n>=0 ) {
+	data.pop_back();
+      }
+    }
+
+    const Val get(const Key &k) const {
+      int idx = kim.get(k);
+      return data[idx].second;
+    }
+    void put(const Key &k, const Val &v) {
+      int idx = kim.get(k);
+      if( idx < 0 ) {
+	push(k,v);
+      }
+      else if( comp(v, data[idx].second) ) {
+	bubble_up(idx, PairType(k,v));
+      }
+      else {
+	bubble_down(idx, PairType(k,v), data.size());
+      }
+    }
+
+    void decrease(const Key &k, const Val &v) {
+      int idx = kim.get(k);
+      bubble_up(idx, PairType(k,v));
+    }
+    void increase(const Key &k, const Val &v) {
+      int idx = kim.get(k);
+      bubble_down(idx, PairType(k,v), data.size());
+    }
+
+  }; // class BinHeap
+
+  
+  template <typename K, typename V, typename M, typename C>
+  int BinHeap<K,V,M,C>::bubble_up(int hole, PairType p) {
+    int par = parent(hole);
+    while( hole>0 && less(p,data[par]) ) {
+      move(data[par],hole);
+      hole = par;
+      par = parent(hole);
+    }
+    move(p, hole);
+    return hole;
+  }
+
+  template <typename K, typename V, typename M, typename C>
+  int BinHeap<K,V,M,C>::bubble_down(int hole, PairType p, int length) {
+    int child = second_child(hole);
+    while(child < length) {
+      if( less(data[child-1], data[child]) ) {
+	--child;
+      }
+      if( !less(data[child], p) )
+	goto ok;
+      move(data[child], hole);
+      hole = child;
+      child = second_child(hole);
+    }
+    child--;
+    if( child<length && less(data[child], p) ) {
+      move(data[child], hole);
+      hole=child;
+    }
+  ok:
+    move(p, hole);
+    return hole;
+  }
+
+} // namespace marci
+
+#endif // BIN_HEAP_HH
Index: src/work/bin_heap_demo.cc
===================================================================
--- src/work/bin_heap_demo.cc	(revision 37)
+++ src/work/bin_heap_demo.cc	(revision 37)
@@ -0,0 +1,91 @@
+#include <iostream>
+#include <bin_heap.hh>
+#include <string>
+#include <map>
+
+using namespace marci;
+using namespace std;
+
+class string_int_map;
+
+typedef BinHeap<string, double, string_int_map> StrDoubleHeap;
+
+class string_int_map : public map<string,int> {
+public:
+  int get(const string &s) {
+    // Bocs, ez igy gaaaany, de nem volt kedvem utananezni, hogy
+    // hogy is mukodik ez a map :)
+    if( count(s) == 0 ) {
+      operator[](s) = StrDoubleHeap::PRE_HEAP;
+    }
+    return operator[](s);
+  }
+  void put(const string &s, int i) {
+      operator[](s) = i;
+  }
+};
+
+
+int main()
+{
+  string_int_map sim;
+  
+  
+  cout << "testing string_int_map default value:\n";
+  cout << "  alma: " << sim.get("alma") << endl;
+
+  cout << "creating the heap\n";
+  StrDoubleHeap heap(sim);
+
+  cout << "heap.push(\"alma\", 15);\n";
+  heap.push("alma", 15);
+
+  cout << "heap.put(\"korte\", 3.4);\n";
+  heap.put("korte", 3.4);
+
+  cout << "heap.get(\"alma\") = " 
+       << heap.get("alma")
+       << endl;
+
+  cout << "heap.top() = "
+       << heap.top() << endl;
+  cout << "heap.topValue() = "
+       << heap.topValue() << endl;
+
+  cout << "heap.decrease(\"alma\", 1.2);\n";
+  heap.put("alma", 1.2);
+
+  cout << "heap.top() = "
+       << heap.top() << endl;
+  cout << "heap.topValue() = "
+       << heap.topValue() << endl;
+
+  cout << "heap.put(\"alma\", 22);\n";
+  heap.put("alma", 22);
+
+  cout << "heap.top() = "
+       << heap.top() << endl;
+  cout << "heap.topValue() = "
+       << heap.topValue() << endl;
+
+  cout << "heap.size() = "
+       << heap.size() << endl;
+  cout << "heap.pop();\n";
+  heap.pop();
+
+  cout << "heap.top() = "
+       << heap.top() << endl;
+  cout << "heap.topValue() = "
+       << heap.topValue() << endl;
+
+  cout << "heap.size() = "
+       << heap.size() << endl;
+  cout << "heap.pop();\n";
+  heap.pop();
+
+  cout << "heap.size() = "
+       << heap.size() << endl;  
+  cout << "heap.empty() = "
+       << (heap.empty()?"true":"false") << endl;  
+}
+
