两种快速排序算法比较

1.选择将第一个元素作为枢纽元。如果输入是随机的,那么这是可以接受的,但如果输入是预排序的或者反排序的,那么这样的枢纽元就产生一个劣质的分割,因为所有的的元素不是被划入S1就是被划入S2。更有甚者,这种情况发生在所有的递归调用中。实际上,如果第一个元素作为枢纽元而且输入是预先排序的,那么快速排序花费的时间将是二次的。

2.三数中值分割法。一组N个数的中值是第[N/2]个最大的数。枢纽元最好的选择是数组的中值。不辛的是,这很难算出,且明显减慢快速排序的速度。这样中值的估计量可以通过随机选取三个元素并用它们的中值作为枢纽元而得到。事实上,随机性没有多大的帮助,因此一般的做法是使用左端、右端和中心位置上的三个元素的中值作为枢纽元。

(后续会加入去随机数作为枢纽元的比较)

下面是用200000个随机数测试的排序耗时:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <windows.h>
#define elementType int
#define Cutoff 3
void Swap(int *a, int *b)
{
    int Tmp = *a;
    *a = *b;
    *b = Tmp;
}
void Qsort1(int A[], int Left, int Right)
{
    int i, j, Pivot;
 
	if(Left < Right)
    {
		Pivot = A[Left];
		i = Left;
		j = Right - 1;
		Swap(&A[Left], &A[Right]);

		while(i <= j)
		{
			while(A[i] < Pivot)
				i++;
			while(A[j] > Pivot)
				j--;
			if(i < j)
			{
				Swap(&A[i], &A[j]);
				i++;
				j--;
			}
			else
				break;
		}
		Swap(&A[i], &A[Right]);

		Qsort1(A, Left, i - 1);
		Qsort1(A, i + 1, Right);
	}
}
void quickSort1(int A[], int N)
{
    Qsort1(A, 0, N - 1);
}
void insertionSort(int A[], int N)
{
     int tmp;
     int j, p;
 
    for( p = 1; p < N; p++ )
     {
         tmp = A[p];
         for( j = p; j > 0 && A[j -1] > tmp; j -- )
             A[j] = A[j-1];
         A[j] = tmp;
     }
 }
int Median3(int A[], int Left, int Right)
{
	int Center = (Left + Right) / 2;
 
	if(A[Left] > A[Center])
		Swap(&A[Left], &A[Center]);
	if(A[Left] > A[Right])
		Swap(&A[Left], &A[Right]);
	if(A[Center] > A[Right])
		Swap(&A[Center], &A[Right]);
 
	Swap(&A[Center], &A[Right - 1]);
	return A[Right - 1];
}
void Qsort2(int A[], int Left, int Right)
{
    int i, j, Pivot;
 
	if(Left + Cutoff <= Right)
    {
		i = Left;
		j = Right - 1;
		Pivot = Median3(A, Left, Right);
		for(; ; )
		{
			while(A[++i] < Pivot){}
			while(A[--j] > Pivot){}	
			if(i < j)
				Swap(&A[i], &A[j]);
			else
				break;
		}
		Swap(&A[i], &A[Right - 1]);
 
		Qsort2(A, Left, i - 1);
		Qsort2(A, i + 1, Right);
	}
	else
		insertionSort(A + Left, Right - Left + 1);
}
void quickSort2(int A[], int N)
{
    Qsort2(A, 0, N - 1);
}
void main()
{
	srand(time(0));
	int a[200000];
	for(int i=0;i<200000;i++)
		a[i] = rand();
	DWORD  dwGTCBegin, dwGTCEnd; 
	printf("200000个随机数各种排序耗时测试:\n");
    dwGTCBegin = GetTickCount();  
    quickSort1(a, 200000);  
    dwGTCEnd = GetTickCount();  
    printf("quickSort1耗时:%5d毫秒\n", dwGTCEnd - dwGTCBegin);
	dwGTCBegin = GetTickCount();  
    quickSort2(a, 200000);  
    dwGTCEnd = GetTickCount();  
    printf("quickSort2耗时:%5d毫秒\n", dwGTCEnd - dwGTCBegin);
}


可以看到采用三中值作为枢纽元确实比选用第一个数作为枢纽元运行速度更快。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值