Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

CTBsortQ.icc

Go to the documentation of this file.
00001 
00006 /*----------------------------------------------------------------------------*/
00007 /* C Tool Box: Designed and implemented by:                                   */
00008 /*    Walter F.J. Mueller   Gesellschaft fuer Schwerionenforschung (GSI)      */
00009 /*                          Planckstrasse 1, D-64291 Darmstadt, Germany       */
00010 /*                  Email:  W.F.J.Mueller@gsi.de                              */
00011 /*                  WWW:    http://www-kp3.gsi.de/www/kp3/people/mueller.html */
00012 /*------------------------------------------+---------------------------------*/
00013 
00014 #include "CTBexceptionBugcheck.hxx"
00015 #include "CTBgrab.hxx"
00016 
00026 
00027 
00028 template <class T, class C>
00029 inline void CTBsortQ<T,C>::operator()(CTBvector<T>& v)
00030 {
00031   const static CTBint dim_stack = 64;       // stack size
00032   const static CTBint max_ins   = 7;        // max. size for straight insert
00033 
00034   CTBgrab<T>  grab;
00035   C           compare;
00036   T           tmp;
00037   CTBuint32   i_ran = 4711 + (CTBuint32) &v; // initialize pseudo random number
00038   CTBint      i_lb  = 0;                    // current partition lower bound
00039   CTBint      i_ub  = v.Size()-1;           // current partition upper bound
00040   CTBint      i_lvl = 0;                    // stack pointer
00041   CTBint      i_stack[dim_stack];
00042 
00043   for (;;) {
00044 
00045     if (i_ub-i_lb < max_ins) {              // if partition small
00046       for (CTBint i = i_lb+1; i <= i_ub; i++) { // use straight insertion sort
00047         CTBint j = i-1;
00048         grab(tmp,v[i]);
00049         while (j >= i_lb && compare(tmp,v[j])) {
00050           grab(v[j+1],v[j]);
00051           j -= 1;
00052         }
00053         grab(v[j+1],tmp);
00054       }
00055       if (i_lvl == 0) return;               // stack empty -> done
00056       i_ub = i_stack[--i_lvl];
00057       i_lb = i_stack[--i_lvl]; 
00058 
00059     } else {                                // if partition large
00060       CTBuint32 i_s = i_ub - i_lb + 1;      // size of partition
00061       CTBint    i_p = i_lb + i_ran % i_s;   // index of pivot value
00062       CTBint    i   = i_lb + 1;
00063       CTBint    j   = i_ub;
00064 
00065       i_ran = i_ran * 69069 + 1;            // update random number
00066       grab.Swap(v[i_lb],v[i_p]);            // move pivot to first slot
00067 
00068       for (;;) {
00069         while (i < j  && compare(v[i],v[i_lb])) i++;
00070         while (j >= i && compare(v[i_lb],v[j])) j--;
00071         if (i >= j) break;
00072         grab.Swap(v[i],v[j]);
00073         j--;
00074         i++;
00075       }
00076       grab.Swap(v[i_lb],v[j]);              // pivot position is v[j]
00077 
00078       if (i_lvl >= dim_stack) 
00079         throw CTBexceptionBugcheck("stack overflow","CTBsortQ");
00080 
00081       if (i_ub-j >= j-i_lb) {               // stack largest, process smallest
00082         i_stack[i_lvl++] = j+1;             // stack upper
00083         i_stack[i_lvl++] = i_ub;
00084         i_ub = j-1;                         // process lower
00085       } else {
00086         i_stack[i_lvl++] = i_lb;            // stack lower
00087         i_stack[i_lvl++] = j-1;
00088         i_lb = j+1;                         // process upper
00089       }
00090     }
00091     
00092   }
00093   
00094   return;
00095 }
00096 
00097 // Note:
00098 //  1. This implementation was inspired by various sources. Note that the
00099 //     code given in Numerical Recipes in C, Chapter 8.4 has a bug !!
00100 
00101 //------------------------------------------+-----------------------------------
00103 
00104 template <class T, class C>
00105 inline void CTBsortQ<T,C>::operator()(CTBvector<CTBint>& ind,
00106                                       const CTBvector<T>& v)
00107 {
00108   const static CTBint dim_stack = 64;       // stack size
00109   const static CTBint max_ins   = 7;        // max. size for straight insert
00110 
00111   CTBgrab<CTBint> grab;
00112   C               compare;
00113   CTBint      tmp;
00114   CTBuint32   i_ran = 4711 + (CTBuint32) &v; // initialize pseudo random number
00115   CTBint      i_lb  = 0;                    // current partition lower bound
00116   CTBint      i_ub  = v.Size()-1;           // current partition upper bound
00117   CTBint      i_lvl = 0;                    // stack pointer
00118   CTBint      i_stack[dim_stack];
00119   
00120   ind.Resize(v.Size());
00121   for (CTBint i = 0; i < v.Size(); i++) ind[i] = i;
00122   
00123   for (;;) {
00124 
00125     if (i_ub-i_lb < max_ins) {              // if partition small
00126       for (CTBint i = i_lb+1; i <= i_ub; i++) { // use straight insertion sort
00127         CTBint j = i-1;
00128         tmp = ind[i];
00129         while (j >= i_lb && compare(v[tmp],v[ind[j]])) {
00130           ind[j+1] = ind[j];
00131           j -= 1;
00132         }
00133         ind[j+1] = tmp;
00134       }
00135       if (i_lvl == 0) return;               // stack empty -> done
00136       i_ub = i_stack[--i_lvl];
00137       i_lb = i_stack[--i_lvl]; 
00138 
00139     } else {                                // if partition large
00140       CTBuint32 i_s = i_ub - i_lb + 1;      // size of partition
00141       CTBint    i_p = i_lb + i_ran % i_s;   // index of pivot value
00142       CTBint    i   = i_lb + 1;
00143       CTBint    j   = i_ub;
00144 
00145       i_ran = i_ran * 69069 + 1;            // update random number
00146       grab.Swap(ind[i_lb],ind[i_p]);        // move pivot to first slot
00147 
00148       for (;;) {
00149         while (i < j  && compare(v[ind[i]],v[ind[i_lb]])) i++;
00150         while (j >= i && compare(v[ind[i_lb]],v[ind[j]])) j--;
00151         if (i >= j) break;
00152         grab.Swap(ind[i],ind[j]);
00153         j--;
00154         i++;
00155       }
00156       grab.Swap(ind[i_lb],ind[j]);          // pivot position is v[j]
00157 
00158       if (i_lvl >= dim_stack) 
00159         throw CTBexceptionBugcheck("stack overflow","CTBsortQ");
00160 
00161       if (i_ub-j >= j-i_lb) {               // stack largest, process smallest
00162         i_stack[i_lvl++] = j+1;             // stack upper
00163         i_stack[i_lvl++] = i_ub;
00164         i_ub = j-1;                         // process lower
00165       } else {
00166         i_stack[i_lvl++] = i_lb;            // stack lower
00167         i_stack[i_lvl++] = j-1;
00168         i_lb = j+1;                         // process upper
00169       }
00170     }
00171     
00172   }
00173   
00174   return;
00175 }

Generated at Fri Oct 24 18:11:30 2003 for CTBbase by doxygen1.2.9-20010812 written by Dimitri van Heesch, © 1997-2001