#pragma once namespace NSet { template class AFX_EXT_CLASS CQuickSort { public: CQuickSort(void) {}; /*!> is quicker than sort_array for arrays larger than about 100 values. */ static void quickSort( T* arr, int sz ); //参数二是参数一的原始索引号 static void quickSort( T* arr, int* iarr, int sz ); protected: static void partSort( T* arr, int istart, int istop, int* jstart, int* jstop ); static void sortFor( T* arr, int sz, int itarget ); static void insertionSort( T* arr, int istart, int istop ); static void partSort( T* arr, int* iarr, int istart, int istop, int* jstart, int* jstop); static void insertionSort( T* arr, int* iarr, int istart, int istop ); static void sortFor( T* arr, int* iarr, int sz, int itarget ); }; ////////////////////////////////////////////////////////////////////////////// //实现代码 #define NSMALL 7 #define FM 7875 #define FA 211 #define FC 1663 #define NSTACK 50 template void CQuickSort::partSort( T* arr, int istart, int istop, int* jstart, int* jstop ) { int ipivot, ileft, iright; T pivotval, tmp; static long int seed = 0L; seed = (seed * FA + FC) % FM; ipivot = (int)(istart + (istop-istart) * (float)seed / (float)FM + .5); if ( ipivot < istart ) ipivot = istart; if ( ipivot > istop ) ipivot = istop; pivotval = arr[ipivot]; for ( ileft=istart, iright=istop; ; ) { while ( arr[ileft] <=pivotval && ileft=pivotval && iright>istart ) iright--; if ( ileft < iright ) { tmp = arr[ileft]; arr[ileft++] = arr[iright]; arr[iright--] = tmp; } else break; } if ( ileft < ipivot ) { tmp = arr[ileft]; arr[ileft++] = arr[ipivot]; arr[ipivot] = tmp; } else if ( ipivot < iright ) { tmp = arr[iright]; arr[iright--] = arr[ipivot]; arr[ipivot] = tmp; } *jstart = iright; *jstop = ileft; } template void CQuickSort::insertionSort( T* arr, int istart, int istop ) { int i, j; T arr_i; for ( i=istart+1; i<=istop; i++ ) { for ( arr_i=arr[i],j=i; j>istart && arr[j-1]>arr_i; j-- ) arr[j] = arr[j-1]; arr[j] = arr_i; } } template void CQuickSort::sortFor( T* arr, int sz, int itarget ) /*!> sorts the array until the 'itarget' element has exactly the right value. The rest of the array must be considered unsorted after the operation, although it will generally be better sorted. */ { int j, k, p = 0, q = sz-1; while( q - p > NSMALL ) { partSort( arr, p, q, &j, &k ); if ( itarget <= j ) q = j; else if ( itarget >= k ) p = k; else return; } insertionSort( arr, p, q ); } template void CQuickSort::quickSort( T* arr, int sz ) /*!> is quicker than sort_array for arrays larger than about 100 values. */ { int pstack[NSTACK], qstack[NSTACK], j, k, p, q, top=0; pstack[top] = 0; qstack[top++] = sz - 1; while( top ) { p = pstack[--top]; q = qstack[top]; while( q - p > NSMALL ) { partSort( arr, p, q, &j, &k ); if ( j-p < q-k ) { pstack[top] = k; qstack[top++] = q; q = j; } else { pstack[top] = p; qstack[top++] = j; p = k; } } insertionSort( arr, p, q ); } } template void CQuickSort::quickSort( T* arr, int* iarr, int sz ) { int pstack[NSTACK], qstack[NSTACK], j, k, p, q, top=0; pstack[top] = 0; qstack[top++] = sz - 1; while( top ) { p = pstack[--top]; q = qstack[top]; while( q - p > NSMALL ) { partSort( arr, iarr, p, q, &j, &k ); if ( j-p < q-k ) { pstack[top] = k; qstack[top++] = q; q = j; } else { pstack[top] = p; qstack[top++] = j; p = k; } } insertionSort( arr, iarr, p, q ); } } template void CQuickSort::partSort( T* arr, int* iarr, int istart, int istop, int* jstart, int* jstop) { int ipivot, ileft, iright; T pivotval, tmp; int itmp; static long int seed = 0L; seed = (seed * FA + FC) % FM; ipivot = (int)(istart + (istop-istart) * (float)seed / (float)FM); if ( ipivot < istart ) ipivot = istart; if ( ipivot > istop ) ipivot = istop; pivotval = arr[ipivot]; for ( ileft=istart, iright=istop; ; ) { while ( arr[ileft] <=pivotval && ileft=pivotval && iright>istart ) iright--; if ( ileft < iright ) { itmp = iarr[ileft]; tmp = arr[ileft]; iarr[ileft] = iarr[iright]; arr[ileft++] = arr[iright]; iarr[iright] = itmp; arr[iright--] = tmp; } else break; } if ( ileft < ipivot ) { itmp = iarr[ileft]; tmp = arr[ileft]; iarr[ileft] = iarr[ipivot]; arr[ileft++] = arr[ipivot]; iarr[ipivot] = itmp; arr[ipivot] = tmp; } else if ( ipivot < iright ) { itmp = iarr[iright]; tmp = arr[iright]; iarr[iright] = iarr[ipivot]; arr[iright--] = arr[ipivot]; iarr[ipivot] = itmp; arr[ipivot] = tmp; } *jstart = iright; *jstop = ileft; } template void CQuickSort::insertionSort( T* arr, int* iarr, int istart, int istop ) { int i, j; T arr_i; int iarr_i; for ( i=istart+1; i<=istop; i++ ) { for ( iarr_i=iarr[i],arr_i=arr[i],j=i; j>istart && arr[j-1]>arr_i; j-- ) { arr[j] = arr[j-1]; iarr[j] = iarr[j-1]; } arr[j] = arr_i; iarr[j] = iarr_i; } } template void CQuickSort::sortFor( T* arr, int* iarr, int sz, int itarget ) { int j, k, p = 0, q = sz-1; while( q - p > NSMALL ) { partSort( arr, iarr, p, q, &j, &k ); if ( itarget <= j ) q = j; else if ( itarget >= k ) p = k; else return; } insertionSort( arr, iarr, p, q ); } #undef NSMALL #undef FM #undef FA #undef FC #undef NSTACK }//namesapce NSet using namespace NSet;