00001
00002
00003
00007
00008 template <class T, class CT, class IT>
00009 std::ostream& operator << (std::ostream& s, const IndexedHeap<T,CT,IT>& t)
00010 {
00011 s << "[";
00012 for (int i=0; i<t.size(); i++) s << t[i] << " " ;
00013 s << "]";
00014 return s;
00015 }
00016
00017
00018
00019
00020 template <class T, class CT, class IT>
00021 IndexedHeap<T,CT,IT>::IndexedHeap ( const CT& comp, const IT& index )
00022 : m_c(&comp), m_i(&index)
00023 {}
00024
00025
00026
00027
00028 template <class T, class CT, class IT>
00029 void IndexedHeap<T,CT,IT>::set( const CT& comp )
00030 {
00031 m_c = ∁
00032 }
00033
00034
00035
00036 template <class T, class CT, class IT>
00037 void IndexedHeap<T,CT,IT>::set ( const IT& index )
00038 {
00039 m_i = &index;
00040 }
00041
00042
00043
00044
00045 template <class T, class CT, class IT>
00046 int IndexedHeap<T,CT,IT>::insert(T t)
00047 {
00048 m_p.push_back(t);
00049 (*m_i)(t) = size()-1;
00050 return upsort(size()-1);
00051 }
00052
00053
00054
00055 template <class T, class CT, class IT>
00056 T& IndexedHeap<T,CT,IT>::top()
00057 {
00058
00059 return m_p.front();
00060 }
00061
00062
00063
00064
00065 template <class T, class CT, class IT>
00066 const T& IndexedHeap<T,CT,IT>::top() const
00067 {
00068
00069 return m_p.front();
00070 }
00071
00072
00073
00074 template <class T, class CT, class IT>
00075 T IndexedHeap<T,CT,IT>::remove_top()
00076 {
00077
00078 T f(m_p[0]);
00079 (*m_i)(f) = -1;
00080 T last = m_p.back();
00081 m_p.pop_back();
00082 if (m_p.size()>0)
00083 {
00084 m_p[0] = last;
00085 (*m_i)(last) = 0;
00086 downsort(0);
00087 }
00088 return f;
00089 }
00090
00091
00092
00093
00094
00095 template <class T, class CT, class IT>
00096 T IndexedHeap<T,CT,IT>::remove(int n)
00097 {
00098
00099 T f(m_p[n]);
00100 (*m_i)(f) = -1;
00101 T last = m_p.back();
00102 m_p.pop_back();
00103 if (m_p.size()>0)
00104 {
00105 m_p[n] = last;
00106 (*m_i)(last) = n;
00107 downsort(n);
00108 }
00109 return f;
00110 }
00111
00112
00113
00114
00115 template <class T, class CT, class IT>
00116 void IndexedHeap<T,CT,IT>::clear()
00117 {
00118 for (typename std::vector<T>::iterator i=m_p.begin(); i!=m_p.end(); ++i)
00119 {
00120 (*m_i)(*i)=-1;
00121 }
00122 m_p.clear();
00123 }
00124
00125
00126
00127
00128 template <class T, class CT, class IT>
00129 int IndexedHeap<T,CT,IT>::father( int i) const
00130 {
00131 return ((i-1)/2);
00132 }
00133
00134
00135
00136 template <class T, class CT, class IT>
00137 int IndexedHeap<T,CT,IT>::rightson( int i) const
00138 {
00139 return (i*2+2);
00140 }
00141
00142
00143
00144 template <class T, class CT, class IT>
00145 int IndexedHeap<T,CT,IT>::leftson( int i) const
00146 {
00147 return (i*2+1);
00148 }
00149
00150
00151
00152 template <class T, class CT, class IT>
00153 void IndexedHeap<T,CT,IT>::swap(int i, int j)
00154 {
00155 T tmp = m_p[i];
00156 m_p[i] = m_p[j];
00157 m_p[j] = tmp;
00158
00159 (*m_i)(m_p[i]) = i;
00160 (*m_i)(m_p[j]) = j;
00161 }
00162
00163
00164
00165
00166
00167 template <class T, class CT, class IT>
00168 int IndexedHeap<T,CT,IT>::upsort(int i)
00169 {
00170
00171 int j = father(i);
00172 while ((i>0)&&(*m_c)(m_p[i],m_p[j]))
00173 {
00174 swap(i,j);
00175 i = j;
00176 j = father(j);
00177 }
00178 return i;
00179 }
00180
00181
00182
00183
00184 template <class T, class CT, class IT>
00185 int IndexedHeap<T,CT,IT>::downsort(int i)
00186 {
00187 do
00188 {
00189
00190 unsigned int ls = leftson(i);
00191 if (ls<m_p.size())
00192 {
00193 bool lc = ((*m_c)(m_p[i],m_p[ls]));
00194 unsigned int rs = ls + 1;
00195 bool rc = true;
00196 if (rs<m_p.size()) rc = ((*m_c)(m_p[i],m_p[rs]));
00197 if ( !lc )
00198 {
00199 if ( !rc )
00200 {
00201 if ((*m_c)(m_p[ls],m_p[rs]))
00202 {
00203 swap(i,ls);
00204 i = ls;
00205 }
00206 else
00207 {
00208 swap(i,rs);
00209 i = rs;
00210 }
00211 }
00212 else
00213 {
00214 swap(i,ls);
00215 i = ls;
00216 }
00217 }
00218 else if ( !rc )
00219 {
00220 swap(i,rs);
00221 i = rs;
00222 }
00223 else return i;
00224 }
00225 else return i;
00226 }
00227 while (true);
00228 return i;
00229 }
00230
00231
00232
00233
00234
00235