1. Use the value of nstart as the threshold value. After a division, values smaller than nstart are left, values greater than nstart are right, and then recursive this process.
void qsort1(long *sortArr, int nStart, int nEnd){int m = 0;long t ;int r ;if(nStart >= nEnd)return ;t = sortArr[nStart] ;m = nStart ;for(r = nStart + 1; r <= nEnd; r++){if(sortArr[r] < t){long temp ;m++ ;temp = sortArr[r] ;sortArr[r] = sortArr[m] ;sortArr[m] = temp ;}}sortArr[nStart] = sortArr[m] ;sortArr[m] = t ;qsort1(sortArr, nStart, m - 1) ;qsort1(sortArr, m + 1, nEnd) ;}
2. Use nstart as the Compare threshold and start nend as the Compare threshold. When a value greater than nstart is found, move it to the end of the series until it reaches the nstart position, in this way, the nstart switching operation after each comparison of the above methods can be omitted as follows:
Sortarr [nstart] = sortarr [m];
Sortarr [m] = T;
void qsort11(long *sortArr, int nStart, int nEnd){int m ;long t ;int i ;long nTemp ;if(nStart >= nEnd)return ;m = nEnd + 1 ;i = nEnd + 1 ;t = sortArr[nStart] ;do{while(sortArr[--i] < t) ;nTemp = sortArr[--m] ;sortArr[m] = sortArr[i] ;sortArr[i] = nTemp ;}while(i != nStart) ;qsort11(sortArr, nStart, m - 1) ;qsort11(sortArr, m + 1, nEnd) ;}
3. Use nstart as the Compare threshold, compare the values at the first two ends of the array, find the first value greater than or equal to nstart from the left, and find the first value less than or equal to nstart from the right, then, exchange and repeat the process until the entire array is traversed, and then the nstart position is switched. In this way, all the less than or equal to nstart are on the left and the greater than or equal to the nstart are on the right, then call this procedure recursively.
void qsort3(long *sortArr, int nStart, int nEnd){int l ;int r ;long t ;long nTemp ;if(nStart >= nEnd)return ;t = sortArr[nStart] ;l = nStart ;r = nEnd + 1 ;for(; l < r; ){do{l++ ;}while(l <= nEnd && sortArr[l] < t) ;do{r-- ;}while(sortArr[r] > t ) ;if(l > r)break ;nTemp = sortArr[l] ;sortArr[l] = sortArr[r] ;sortArr[r] = nTemp ;}sortArr[nStart] = sortArr[r] ;sortArr[r] = t ;qsort3(sortArr, nStart, r - 1) ;qsort3(sortArr, r + 1, nEnd) ;}
4. Select a value in the array as the threshold value for comparison.
void qsort3r(long *sortArr, int nStart, int nEnd){int l ;int r ;int k ;long t ;long nTemp ;int nRand ;double drate ;if(nStart >= nEnd)return ;nRand = rand() ;drate = nRand / RAND_MAX ;k = nStart + (int)((nEnd - nStart) * drate) ;t = sortArr[k] ;sortArr[k] = sortArr[nStart] ;sortArr[nStart] = t ;l = nStart ;r = nEnd + 1 ;for(; l < r; ){do{l++ ;}while(l <= nEnd && sortArr[l] < t) ;do{r-- ;}while(sortArr[r] > t ) ;if(l > r)break ;nTemp = sortArr[l] ;sortArr[l] = sortArr[r] ;sortArr[r] = nTemp ;}sortArr[nStart] = sortArr[r] ;sortArr[r] = t ;qsort3r(sortArr, nStart, r - 1) ;qsort3r(sortArr, r + 1, nEnd) ;}
5. Hill sorting
It is a sort of incremental decrease (diminishing increment), insert a special case of the hill sort during sorting, and the increment is 1. The Hill sort can achieve good performance according to the incremental selection.
void shellsortKn(long a[], int l, int r){ int i, h; for (h = 1; h <= (r-l)/9; h = 3*h+1) ;for ( ; h > 0; h /= 3){for (i = l+h; i <= r; i++){ int j = i; long v = a[i]; while (j >= l+h && less(v, a[j-h])){a[j] = a[j-h]; j -= h;}a[j] = v; }}}
Test the preceding algorithm.
#define maxN 10000000typedef long itemType;#define randomLong rand()long doit(void (*sortprog)(), itemType a[], int l, int r){long t ;t = GetTickCount() ;(*sortprog)(a, l, r) ;return (GetTickCount() - t) ;}int main(){itemType *a, *b; int N; int c1, c2, c3, c4, c5;srand( GetTickCount() ); a = malloc(maxN * sizeof(itemType)); b = malloc(maxN * sizeof(itemType)); printf(" N q1 q11 q3 q3r shs\n");for (N = 12500; N <= maxN; N *= 2) { randArray(b, N); copyArray(a, b, N); c1 = doit(qsort1, a, 0, N-1); copyArray(a, b, N); c2 = doit(qsort11, a, 0, N-1); copyArray(a, b, N); c3 = doit(qsort3, a, 0, N-1);copyArray(a, b, N); c4 = doit(qsort3r, a, 0, N-1); copyArray(a, b, N); c5 = doit(shellsortKn, a, 0, N-1); printf("%7d %6d %6d %6d %6d %6d\n", N, c1, c2, c3, c4, c5); }free(a);free(b);scanf("%d", &N) ;return 0 ;}
My machine configuration is as follows:
Intel core2 p7450
2 GB memory
Windows 7 32bit
Is the result of running on my machine
Refer:
[1] programming Pearl Second Edition http://book.douban.com/subject/3227098/
[2] http://en.wikipedia.org/wiki/Shell_sort
[3] The beauty of Mathematics
[4] shellsort
Void qsort1 (long * sortarr, int nstart, int nend)
{
Int m = 0;
Long T;
Int R;
If (nstart> = nend)
Return;
T = sortarr [nstart];
M = nstart;
For (r = nstart + 1; r <= nend; r ++)
{
If (sortarr [R] <t)
{
Long temp;
M ++;
Temp = sortarr [R];
Sortarr [R] = sortarr [m];
Sortarr [m] = temp;
}
}
Sortarr [nstart] = sortarr [m];
Sortarr [m] = T;
Qsort1 (sortarr, nstart, m-1 );
Qsort1 (sortarr, m + 1, nend );
}