00001 #ifndef MINMAXHEAP_HPP
00002 #define MINMAXHEAP_HPP
00003
00004 #include "vc6compat.h"
00005
00006 #include <algorithm>
00007
00008 struct compsmaller
00009 {
00010 template< typename T1, typename T2 >
00011 bool operator()( const T1& v1, const T2& v2 )
00012 {
00013 return v1 < v2;
00014 }
00015 };
00016
00017 struct compbigger
00018 {
00019 template< typename T1, typename T2 >
00020 bool operator()( const T1& v1, const T2& v2 )
00021 {
00022 return v1 > v2;
00023 }
00024 };
00025
00026 template <typename T, typename cmps, typename cmpb>
00027 class minmaxheap {
00028 private:
00029 int size;
00030 int filled;
00031 T* heap;
00032 cmps s;
00033 cmpb b;
00034 void upheap(const int position);
00035 void downheap();
00036 public:
00037 minmaxheap(int size_) : size(size_), filled(0) { heap=new T[size]; }
00038 ~minmaxheap() { delete[] heap; }
00039 const T& operator[] (int n) const { return heap[n]; }
00040 const T& operator() () const { return heap[0]; }
00041 void put (const T& elem);
00042 void clear() { filled=0; }
00043 };
00044
00045
00046 template <typename T, typename cmps, typename cmpb>
00047 void minmaxheap<T, cmps, cmpb>::upheap(const int position) {
00048 int sohn=position;
00049 int vater=sohn/2;
00050 while (sohn!=0) {
00051 if (b(heap[sohn],heap[vater])) return;
00052 std::swap(heap[sohn], heap[vater]);
00053 sohn=vater;
00054 vater=sohn/2;
00055 }
00056 }
00057
00058 template <typename T, typename cmps, typename cmpb>
00059 void minmaxheap<T, cmps, cmpb>::downheap() {
00060 int vater=0;
00061 int lsohn=2*vater+1;
00062 while (lsohn<filled) {
00063 if (s(heap[lsohn],heap[vater])) {
00064 if ((lsohn+1<filled) && (s(heap[lsohn+1],heap[lsohn]))) {
00065
00066 std::swap(heap[lsohn+1], heap[vater]);
00067 vater=lsohn+1;
00068 } else {
00069
00070 std::swap(heap[lsohn], heap[vater]);
00071 vater=lsohn;
00072 }
00073 } else {
00074
00075 if ((lsohn+1<filled) && (s(heap[lsohn+1],heap[vater]))) {
00076
00077 std::swap(heap[lsohn+1], heap[vater]);
00078 vater=lsohn+1;
00079 } else {
00080 return;
00081
00082 }
00083 }
00084 lsohn=2*vater+1;
00085 }
00086 }
00087
00088
00089 template <typename T, typename cmps, typename cmpb>
00090 void minmaxheap<T, cmps, cmpb>::put(const T& elem) {
00091
00092 if (filled<size) {
00093
00094 heap[filled]=elem;
00095 upheap(filled++);
00096 } else {
00097
00098 if (b(elem,heap[0])) {
00099 heap[0]=elem;
00100 downheap();
00101 }
00102 }
00103
00104 }
00105
00106 template <typename T>
00107 class minheap: public minmaxheap<T, compsmaller, compbigger> {
00108 public:
00109 minheap(int size_) : minmaxheap<T, compsmaller, compbigger> (size_) { }
00110 const T& max() const { return minmaxheap<T, compsmaller, compbigger>::operator()(); }
00111 };
00112
00113 template <typename T>
00114 class maxheap: public minmaxheap<T, compbigger, compsmaller> {
00115 public:
00116 maxheap(int size_) : minmaxheap<T, compbigger, compsmaller> (size_) { }
00117 const T& min() const { return minmaxheap<T, compbigger, compsmaller>::operator()(); }
00118 };
00119
00120
00121 #endif
00122