几种快排方法比较

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

【3】数学之美番外篇:快排为什么那样快

【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) ;
}

posted on 2010-07-09 23:41  wuzy  阅读(522)  评论(0编辑  收藏  举报

导航