dyn_sort_utils.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
00041 */
00042 
00043 # ifndef DYN_SORT_UTILS_H 
00044 # define DYN_SORT_UTILS_H
00045 
00046 # include <aleph.H>
00047 # include <ahFunction.H>
00048 # include <tpl_arrayStack.H>
00049 # include <tpl_dynArray.H>
00050 
00051 
00052 namespace Aleph
00053 {
00054 
00055 
00077     template <class T, class Compare > inline
00078 void selection_sort(DynArray<T> & a)
00079 {
00080   const int n = a.size();
00081 
00082   for (int i = 0; i < n - 1; i++)
00083     {
00084       int min = i;
00085 
00086       for (int j = i + 1; j < n; j++)
00087      if (Compare()(static_cast<const T&>(a.access(j)), 
00088                 static_cast<const T&>(a.access(min))))
00089        min = j;
00090 
00091       if (Compare()(static_cast<const T&>(a.access(min)), 
00092               static_cast<const T&>(a.access(i))))
00093      Aleph::swap(static_cast<T&>(a.access(min)), 
00094               static_cast<T&>(a.access(i)));
00095     }
00096 }
00097 
00098 
00099     template <class T> inline
00100 void selection_sort(DynArray<T> & a)
00101 {
00102   selection_sort<T, Aleph::less<T> >(a);
00103 }
00104 
00125     template <class T, class Compare> inline
00126 void bubble_sort(DynArray<T> & a)
00127 {
00128   const int n = a.size();
00129 
00130   for (int i = 0; i < n - 1; i++)
00131     for (int j = n - 1; j > i; j--)
00132       {
00133      if (Compare()(static_cast<const T&>(a.access(j)), 
00134                 static_cast<const T&>(a.access(j - 1))))
00135        {
00136          Aleph::swap(static_cast<T&>(a.access(j - 1)), 
00137                static_cast<T&>(a.access(j)));
00138        }
00139       }
00140 }
00141 
00142 
00143     template <class T> inline
00144 void bubble_sort(DynArray<T> & a)
00145 {
00146   bubble_sort<T, Aleph::less<T> >(a);
00147 }
00148 
00173     template <class T, class Compare> inline
00174 void insertion_sort(DynArray<T> & a)
00175 {
00176   const int n = a.size();
00177 
00178   for (int i = 1; i < n; i++)
00179     {
00180       T tmp = a.access(i);
00181       int j = i;
00182       while (j > 0 and 
00183           Compare()(static_cast<const T&>(a.access(j - 1)), tmp))
00184      {
00185        a.access(j) = a.access(j - 1);
00186        j--;
00187      }
00188 
00189       a.access(j) = tmp;
00190     }
00191 }
00192 
00193     template <class T> inline
00194 void insertion_sort(DynArray<T> & a)
00195 {
00196   insertion_sort<T, Aleph::greater<T> >(a);
00197 }
00198 
00218     template <class T, class Compare> inline
00219 void shellsort(DynArray<T> & a)
00220 {
00221   const int n = a.size();
00222   int incs[16] = { 1391376, 463792, 198768, 86961, 
00223              33936, 13776, 4592, 1968, 861, 
00224              336, 112, 48, 21, 7, 3, 1 }; 
00225 
00226   for (int k = 0; k < 16; k++) 
00227     { 
00228       const int h = incs[k]; 
00229       for (int i = h; i < n; i++) 
00230       { 
00231      T tmp = a.access(i); 
00232      int j = i;
00233 
00234      while (j >= h and 
00235             Compare()(tmp, static_cast<const T&>(a.access(j - h))))
00236        {
00237          a.access(j) = a.access(j - h);
00238          j -= h;
00239        } 
00240 
00241      a.access(j) = tmp;
00242       } 
00243     } 
00244 }
00245 
00246     template <class T> inline
00247 void shellsort(DynArray<T> & a)
00248 {
00249   shellsort<T, Aleph::less<T> >(a);
00250 }
00251 
00252 
00253 inline static int back_index(const int & i) { return i - 1; }
00254 
00255 
00256     template <class T, class Compare> inline
00257 static void siftUp(DynArray<T> & table, const size_t & n) 
00258 { 
00259   int p;
00260   for (int i = n; i > 1; i = p) 
00261     {
00262       p = i >> 1;     // c = i/2 
00263 
00264       if (Compare()(static_cast<const T&>(table.access(back_index(p))), 
00265               static_cast<const T&>(table.access(back_index(i)))))
00266      return;
00267       Aleph::swap(static_cast<T&>(table.access(back_index(p))), 
00268             static_cast<T&>(table.access(back_index(i))));
00269     }
00270 }
00271 
00272 
00273 
00274     template <class T, class Compare> inline
00275 static void siftDown(DynArray<T> & table, const size_t & n) 
00276 {
00277   unsigned i = 1;
00278 
00279   while (true)
00280     {
00281       int c = i << 1; // c = 2*i
00282 
00283       if (c > n) 
00284      return;
00285 
00286       if (c + 1 <= n)
00287      if (Compare()(static_cast<const T&>(table.access(back_index(c + 1))), 
00288                 static_cast<const T&>(table.access(back_index(c)))))
00289        c++;
00290 
00291       if (Compare()(static_cast<const T&>(table.access(back_index(i))),
00292               static_cast<const T&>(table.access(back_index(c)))))
00293      return; 
00294 
00295       Aleph::swap(static_cast<T&>(table.access(back_index(c))), 
00296             static_cast<T&>(table.access(back_index(i))));
00297       i = c;
00298     }
00299 }
00300 
00301 
00322     template <class T> inline
00323 void heapsort(DynArray<T> & a)
00324 {
00325   const int n = a.size();
00326 
00327   int i;
00328   for (i = 2; i <= n; i++)
00329     siftUp<T, Aleph::greater<T> >(a, i);
00330 
00331   for (i = n; i >= 2; i--)
00332     {
00333       Aleph::swap(static_cast<T&>(a.access(0)), 
00334             static_cast<T&>(a.access(i - 1)));
00335 
00336       siftDown<T, Aleph::greater<T> >(a, i - 1);
00337     }
00338 }
00339   
00340 
00341     template <class T, class Compare> inline
00342 int partition(DynArray<T> & a, const int & l, const int & r)
00343 {
00344   int i = l - 1, 
00345       j = r;
00346   const T & pivot = a.access(r);
00347 
00348   while (true)
00349     {
00350       while (Compare()(static_cast<const T&>(a.access(++i)), pivot)) { }
00351 
00352       while (Compare()(pivot, static_cast<const T&>(a.access(--j))))
00353      if (j == l)
00354        break;
00355 
00356       if (i >= j)
00357      break;
00358 
00359       Aleph::swap(static_cast<T&>(a.access(i)), static_cast<T&>(a.access(j)));
00360     }
00361 
00362   Aleph::swap(static_cast<T&>(a.access(i)), static_cast<T&>(a.access(r)));
00363 
00364   return i;
00365 }
00366 
00367 
00368     template <class T, class Compare> inline static
00369 void quicksort_rec(DynArray<T> & a, const int & l, const int & r)
00370 {
00371   if (r <= l) 
00372     return;
00373 
00374   int i = partition<T, Compare>(a, l, r);
00375 
00376   if (i - l < r - i)
00377     {
00378       quicksort_rec<T, Compare>(a, l, i - 1);
00379       quicksort_rec<T, Compare>(a, i + 1, r);
00380     }
00381   else
00382     {
00383       quicksort_rec<T, Compare>(a, i + 1, r);
00384       quicksort_rec<T, Compare>(a, l, i - 1);
00385     }
00386 }
00387 
00388 # define push2(stack, a, b)  stack.push(b); stack.push(a);
00389 
00421     template <class T, class Compare> inline
00422 void quicksort(DynArray<T> & a)
00423 {
00424   int i, l = 0, r = a.size() -1;
00425 
00426   FixedStack<int, 40> stack;
00427 
00428   push2(stack, l, r);
00429 
00430   while (not stack.is_empty())
00431     {
00432       l = stack.pop(); r = stack.pop();
00433 
00434       if (r <= l) 
00435      continue;
00436 
00437       i = partition<T, Compare>(a, l, r);
00438 
00439       if (i - l > r - i)
00440      {
00441        push2(stack, l, i - 1); push2(stack, i + 1, r);
00442      }
00443       else 
00444      {
00445        push2(stack, i + 1, r); push2(stack, l, i - 1); 
00446      } 
00447     }
00448 }
00449 
00450     template <class T> inline
00451 void quicksort(DynArray<T> & a)
00452 {
00453   quicksort<T, Aleph::less<T> >(a);
00454 }
00455 
00456 
00457 # undef push2
00458 
00474     template <class T, class Compare> inline
00475 int search_extreme(DynArray<T>& a, const int & l, const int & r)
00476 {
00477   int extreme_index = l;
00478 
00479   for (int i = l + 1; i <= r; i++)
00480     if (Compare()(static_cast<const T&>(a.access(i)), 
00481             static_cast<const T&>(a.access(extreme_index))))
00482       extreme_index = i;
00483 
00484   return extreme_index;
00485 }
00486 
00491     template <class T> inline
00492 int search_min(DynArray<T>& a, const int & l, const int & r)
00493 {
00494   return search_extreme<T, Aleph::less<T> >(a, l, r);
00495 }
00496 
00501     template <class T> inline
00502 int search_max(DynArray<T>& a, const int & l, const int & r)
00503 {
00504   return search_extreme<T, Aleph::greater<T> >(a, l, r);
00505 } 
00506 
00539     template <class T, class Compare> inline
00540 int binary_search(DynArray<T> & a, const T & x, int l, int r)
00541 {
00542   while (l <= r)
00543     {
00544       int m = (l + r)/2;
00545 
00546       if (Compare() (x, static_cast<const T&>(a.access(m))))
00547      r = m -1;
00548       else if (Compare() (static_cast<const T&>(a.access(m)), x))
00549      l = m + 1;
00550       else
00551      return m; // clave encontrada
00552     }
00553 
00554   return -1;
00555 }
00556 
00557     template <class T> inline
00558 int binary_search(DynArray<T> & a, const T & x, const int & l, const int & r)
00559 {
00560   return binary_search<T, Aleph::less<T> >(a, x, l, r);
00561 }
00562 
00563 
00564     template <class T> inline
00565 int binary_search(DynArray<T> & a, const T & x)
00566 {
00567   return binary_search<T>(a, x, 0, static_cast<int>(a.size()) - 1);
00568 }
00569 
00570 
00571 } // end namespace Aleph
00572 
00573 
00574 
00575 # endif // DYN_SORT_UTILS_H

Leandro R. León