几种快排方法比较
1、以nStart的值作为阈值划分,一次划分后小于nStart的值在左边,大于nStart的值在右边,然后递归此过程
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、从nStart作为比较的阈值,从nEnd开始比较,当发现有比nStart大的值的时候即将其挪到数列的后面,直到到达nStart的位置,这样可以省略上面的方法每次比较结束后的交换nStart的操作如下:
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、以nStart作为比较的阈值,从数组首位两端进行比较,从左开始找到第一个大于等于nStart的值,从右开始找到第一个小于等于nStart的值,然后交换之,重复此过程直到遍历完整个数组,然后交换nStart的位置,这样小于等于nStart的都在其左边,大于等于的都在其右边,然后递归调用此过程
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、随即选取数组中的一个值作为阈值进行比较,其他同方法3
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、希尔排序
是一种增量递减(diminishing increment)排序,插入排序时希尔排序的一个特例,及增量为1,希尔排序根据增量选取的不同可得到很好的性能
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;
}
}
}
对上述算法进行测试
#define maxN 10000000
typedef 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 ;
}
我的机器配置如下:
intel core2 P7450
内存2G
windows 7 32bit
参考:
【1】 编程珠玑第二版 http://book.douban.com/subject/3227098/
【2】http://en.wikipedia.org/wiki/Shell_sort
【4】Shellsort
浙公网安备 33010602011771号