|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
namespace NSet
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
|
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 );
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><C7B2><EFBFBD>һ<EFBFBD><D2BB>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
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 );
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//ʵ<>ִ<EFBFBD><D6B4><EFBFBD>
|
|
|
|
|
|
|
|
|
|
|
|
#define NSMALL 7
|
|
|
|
|
|
#define FM 7875
|
|
|
|
|
|
#define FA 211
|
|
|
|
|
|
#define FC 1663
|
|
|
|
|
|
#define NSTACK 50
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
|
void CQuickSort<T>::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<istop ) ileft++;
|
|
|
|
|
|
while ( arr[iright]>=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 <class T>
|
|
|
|
|
|
void CQuickSort<T>::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 <class T>
|
|
|
|
|
|
void CQuickSort<T>::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 <class T>
|
|
|
|
|
|
void CQuickSort<T>::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 <class T>
|
|
|
|
|
|
void CQuickSort<T>::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 <class T>
|
|
|
|
|
|
void CQuickSort<T>::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<istop ) ileft++;
|
|
|
|
|
|
while ( arr[iright]>=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 <class T>
|
|
|
|
|
|
void CQuickSort<T>::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 <class T>
|
|
|
|
|
|
void CQuickSort<T>::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;
|