|
STK++ 1.0
|
00001 /*--------------------------------------------------------------------*/ 00002 /* Copyright (C) 2006-2007 Serge Iovleff 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as 00006 published by the Free Software Foundation; either version 2 of the 00007 License, or (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public 00015 License along with this program; if not, write to the 00016 Free Software Foundation, Inc., 00017 59 Temple Place, 00018 Suite 330, 00019 Boston, MA 02111-1307 00020 USA 00021 00022 Contact : Serge.Iovleff@stkpp.org 00023 */ 00024 00025 /* 00026 * Project: DManager 00027 * Purpose: sorting method acting on Containers 00028 * Author: Serge Iovleff, serge.iovleff@stkpp.org 00029 * 00030 **/ 00031 00037 #ifndef STK_HEAPSORT_H 00038 #define STK_HEAPSORT_H 00039 00040 #include "../../Sdk/include/STK_ITContainer1D.h" 00041 #include "../../Sdk/include/STK_ITContainer2D.h" 00042 00043 #ifdef STK_HEAPSORT_DEBUG 00044 #include "../../STKernel/include/STK_Display1D.h" 00045 #endif 00046 00047 namespace STK 00048 { 00049 00054 template<class TYPE, class TContainer1D> 00055 void heapSort( ITContainer1D<TYPE, TContainer1D>& T) 00056 { 00057 // number of elements 00058 const Integer nb_elt = T.size(); 00059 if (nb_elt < 2) return; 00060 00061 // if the container is base one, shift0 = 0 and shift1 = 1 00062 Integer shift1 = T.first(), shift0 = T.first() - 1; 00063 00064 // create heap 00065 for (Integer first = nb_elt/2; first > 0; -- first) 00066 { 00067 // the value value to insert in the heap 00068 TYPE value = T[shift0 + first]; 00069 // organize the heap 00070 Integer i=first, j=2*first; 00071 while (j <= nb_elt) 00072 { 00073 // j+1 is greatest child 00074 if ( j < nb_elt && T[shift0 + j] < T[shift1 + j] ) j++; 00075 // we have find a child gt value 00076 if (value >= T[shift0 + j]) break; 00077 // else shift the inner value 00078 T[shift0 + i] = T[shift0 + j]; 00079 // go down in the tree 00080 i = j; 00081 j*= 2; 00082 } 00083 // plug value in its final location 00084 T[shift0 + i] = value; 00085 } 00086 #ifdef STK_HEAPSORT_DEBUG 00087 std::cout << "T=\n" << T.asLeaf() << "\n"; 00088 #endif 00089 // sort T 00090 for (Integer last = nb_elt;;) 00091 { // the value to sort 00092 TYPE value = T[shift0 + last]; 00093 // Put the top of the heap at the end 00094 T[shift0 + last] = T[shift1]; 00095 // decrease last. last==1 : we end the job 00096 if (--last == 1) 00097 { T[shift1] = value; 00098 break; 00099 } 00100 // organize the heap 00101 Integer i=1, j=2; 00102 while (j <= last) 00103 { // j+1 is greatest child 00104 if ( j < last && T[shift0 + j] < T[shift1 + j] ) j++; 00105 // we have find a child gt value 00106 if (value >= T[shift0 + j]) break; 00107 // else shift the inner value 00108 T[shift0 + i] = T[shift0 + j]; 00109 // go down in the tree 00110 i = j; 00111 j*= 2; 00112 } 00113 // plug value in its final location 00114 T[shift0 + i] = value; 00115 } 00116 } 00117 00124 template<class TYPE, class TContainer1D> 00125 void heapSort( const ITContainer1D<TYPE, TContainer1D>& T 00126 , ITContainer1D<TYPE, TContainer1D>& Tsort 00127 ) 00128 { 00129 // copy T in Tsort 00130 Tsort.asLeaf() = T.asLeaf(); 00131 // number of elements 00132 const Integer nb_elt = Tsort.size(); 00133 if (nb_elt < 2) return; 00134 00135 // if the container is base one, shift0 = 0 and shift1 = 1 00136 Integer shift1 = Tsort.first(), shift0 = Tsort.first() - 1; 00137 00138 // create heap 00139 for (Integer first = nb_elt/2; first > 0; -- first) 00140 { 00141 // the value value to insert in the heap 00142 TYPE value = Tsort[shift0 + first]; 00143 // organize the heap 00144 Integer i=first, j=2*first; 00145 while (j <= nb_elt) 00146 { 00147 // j+1 is greatest child 00148 if ( j < nb_elt && Tsort[shift0 + j] < Tsort[shift1 + j] ) j++; 00149 // we have find a child gt value 00150 if (value >= Tsort[shift0 + j]) break; 00151 // else shift the inner value 00152 Tsort[shift0 + i] = Tsort[shift0 + j]; 00153 // go down in the tree 00154 i = j; 00155 j*= 2; 00156 } 00157 // plug value in its final location 00158 Tsort[shift0 + i] = value; 00159 } 00160 #ifdef STK_HEAPSORT_DEBUG 00161 std::cout << "T=\n" << Tsort.asLeaf() << "\n"; 00162 #endif 00163 // sort T 00164 for (Integer last = nb_elt;;) 00165 { // the value to sort 00166 TYPE value = Tsort[shift0 + last]; 00167 // Put the top of the heap at the end 00168 Tsort[shift0 + last] = Tsort[shift1]; 00169 // decrease last. last==1 : we end the job 00170 if (--last == 1) 00171 { Tsort[shift1] = value; 00172 break; 00173 } 00174 // organize the heap 00175 Integer i=1, j=2; 00176 while (j <= last) 00177 { // j+1 is greatest child 00178 if ( j < last && Tsort[shift0 + j] < Tsort[shift1 + j] ) j++; 00179 // we have find a child gt value 00180 if (value >= Tsort[shift0 + j]) break; 00181 // else shift the inner value 00182 Tsort[shift0 + i] = Tsort[shift0 + j]; 00183 // go down in the tree 00184 i = j; 00185 j*= 2; 00186 } 00187 // plug value in its final location 00188 Tsort[shift0 + i] = value; 00189 } 00190 } 00191 00199 template<class TYPE, class TContainer1D, class TContainer1DInt> 00200 void heapSort( ITContainer1D<Integer, TContainer1DInt> & I 00201 , ITContainer1D<TYPE, TContainer1D> const& T 00202 ) 00203 { 00204 // number of elements 00205 Integer nb_elt = T.size(); 00206 00207 // create index array 00208 I.resize(T.range()); 00209 Integer first = I.first(), last = I.last(); 00210 for (Integer i=first; i<=last; i++) 00211 { I[i] = i;} 00212 00213 if (nb_elt < 2) return; 00214 00215 // if the container is base one, shift0 = 0 and shift1 = 1 00216 Integer shift1 = T.first(), shift0 = T.first() - 1; 00217 00218 // create heap 00219 for (first = nb_elt/2; first > 0; --first) 00220 { 00221 // the value value to insert in the heap 00222 TYPE value = T[I[shift0 + first]]; 00223 // organize the heap 00224 Integer i=first, j=2*first; 00225 while (j <= nb_elt) 00226 { 00227 // j+1 is greatest child 00228 if ( j < nb_elt && T[I[shift0 + j]] < T[I[shift1 + j]] ) j++; 00229 // we have find a child lt value 00230 if (value >= T[I[shift0 + j]]) break; 00231 // else shift the inner values 00232 I[shift0 + i] = I[shift0 + j]; 00233 // go down in the tree 00234 i = j; 00235 j*= 2; 00236 } 00237 // plug value in its final location 00238 I[shift0 + i] = shift0 + first; 00239 } 00240 #ifdef STK_HEAPSORT_DEBUG 00241 std::cout << "I=\n" << I <<"\n"; 00242 #endif 00243 // sort T 00244 for (Integer last = nb_elt;;) 00245 { 00246 // the value to sort 00247 Integer ivalue = I[shift0 + last]; 00248 TYPE value = T[ivalue]; 00249 // Put the top of the heap at the end 00250 //T[shift0 + last] = T[shift1]; 00251 I[shift0 + last] = I[shift1]; 00252 // decrease last. last==1 : we end the job 00253 if (--last == 1) 00254 { //T[shift1] = value; 00255 I[shift1] = ivalue; 00256 break; 00257 } 00258 // organize the heap 00259 Integer i=1, j=2; 00260 while (j <= last) 00261 { // j+1 is greatest child 00262 if ( j < last && T[I[shift0 + j]] < T[I[shift1 + j]] ) j++; 00263 // we have find a child gt value 00264 if (value >= T[I[shift0 + j]]) break; 00265 // else shift the inner value 00266 // T[shift0 + i] = T[shift0 + j]; 00267 I[shift0 + i] = I[shift0 + j]; 00268 // go down in the tree 00269 i = j; 00270 j*= 2; 00271 } 00272 // plug value in its final location 00273 // T[shift0 + i] = value; 00274 I[shift0 + i] = ivalue; 00275 } 00276 #ifdef STK_HEAPSORT_DEBUG 00277 std::cout << "I=\n" << I <<"\n"; 00278 #endif 00279 } 00280 00281 00287 template<class TYPE, class TContainer1D, class TContainer1DInt> 00288 void applySort( ITContainer1D<TYPE, TContainer1D>& T 00289 , ITContainer1D<Integer, TContainer1DInt> const& I 00290 ) 00291 { 00292 #ifdef STK_DEBUG 00293 if (I.range() != T.range()) 00294 { throw runtime_error("In applySort(T, I) " 00295 "incompatible lengths\n"); 00296 } 00297 #endif 00298 TContainer1D A(T.range()); 00299 const Integer first = I.first(), last = I.last(); 00300 for (Integer i=first; i<= last; i++) 00301 { 00302 A[i] = T[I[i]]; 00303 } 00304 T.asLeaf() = A.asLeaf(); 00305 } 00306 00312 template < class TYPE, class TContainer2D, class TContainer1DInt> 00313 void applySort( ITContainer2D< TYPE, TContainer2D>& T 00314 , ITContainer1D<Integer, TContainer1DInt> const& I 00315 ) 00316 { 00317 #ifdef STK_DEBUG 00318 if (I.range() != T.rangeVe()) 00319 { throw runtime_error("In applySort(T, I) " 00320 "incompatible lengths\n"); 00321 } 00322 #endif 00323 TContainer2D A(T.rangeVe(), T.rangeHo()); 00324 const Integer first = I.first(), last = I.last(); 00325 for (Integer i=first; i<= last; i++) 00326 { 00327 A(i) = T(I[i]); 00328 } 00329 T.asLeaf() = A.asLeaf(); 00330 } 00331 00332 } // namespace STK 00333 00334 #endif /*STK_HEAPSORT_H*/