STK++ 1.0
STK_HeapSort.h
Go to the documentation of this file.
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*/