八大排序算法(2)_快速排序的优化

        最经在看大话数据结构。本文中的优化内容基本是该书上的总结。代码可能有点不同。

       快速排序是21世纪经典的十大算法之一。其思路为:选取一个中枢元素,然后通过一种方法,在该序列中唯一确定了该中枢位置,即是前面的都小于该中枢值,后面的都比该中枢值大。从而将待排序列,分割成了两半。当然这是最好的情况下,此时效果最好。下面从3方面来优化。

未经过优化的排序为:

void quicksort(int a[],int first,int last)
{
	if(first<last)
	{
		 int i=first,j=last; 
		 int tmp=a[first];
		 while( i<j )
		 {
			 while(i<j && a[j]>=tmp)
			 --j;		// find the first index j that a[j] < tmp from right to left
			 if(i<j)
				 a[i++]=a[j];		// cover the a[i]. 
			 while( i<j && a[i]<tmp)
				 i++;			//find the first index i that a[i]>tmp from left to right
			 if(i<j)
				 a[j--]=a[i];		//cover the a[j] 
		 }
		if(i==j)
			a[i]=tmp;
		quicksort(a,first,i-1);
		quicksort(a,i+1,last);
	}
}
缺点:

1.中枢值每次都选取为序列首元素。不能保证尽可能为中间值。

2.对于数据的排序而言,对于小数据而言,使用直接插入排序效果可能更好。

3.快速排序使用了两个递归调用,能不能进一步优化。

优化 从3方面进行:

1.选取中枢值。这里可以采用随机的方法,但是产生随机序列本身也要耗时,效果可能不好,从概率的角度来看,选取头,中,尾三处的值。然后取中间值。作为中枢值,效果较好。

/***********************************************************************
QuickSort optimized
1. optimize base value
2. optimize sort scale n 
3. optimize the way of recusion (tail recursion)
***********************************************************************/
#include <iostream>
#include <ctime>
using namespace std;
void Swap(int &x,int &y)
{
	int tmp=x;
	x=y;
	y=x;
}
//Unoptimized QuickSort
void quicksort(int a[],int first,int last)
{
	while(first<last)
	{
		 int i=first,j=last; 
		 int mid=(first+last)/2; //mid value
		
		 if(a[first]>a[last])
			 Swap(a[first],a[last]); // ensure index pos=first value less than last
		 if(a[mid]>a[last])
			Swap(a[mid],a[last]);  // ensure index pos=mid value less than last
		 if(a[first]>a[mid])
			 Swap(a[first],a[mid]); // ensure first val less than mid
		 int tmp=a[first];  //now  a[first] is the mid-value of low -mid-high

		 while( i<j )
		 {
			 while(i<j && a[j]>=tmp)
				 --j;		// find the first index j that a[j] < tmp from right to left
			 if(i<j)
				 a[i++]=a[j];		// cover the a[i]. 
			 while( i<j && a[i]<tmp)
				 i++;			//find the first index i that a[i]>tmp from left to right
			 if(i<j)
				 a[j--]=a[i];		//cover the a[j] 
		 }
		if(i==j)
			a[i]=tmp;
		quicksort(a,first,i-1);
		first=i+1;			//reduce one recursion
		//quicksort(a,i+1,last);
	}
}

void QuickSort(int a[],int len)
{	
	if(len>32)
		quicksort(a,0,len-1);
	//else   // when data scale less than 32 use InsertSort
	//	InsertSort(a,len); 
}
void print(int a[],int len)
{
	for(int i=0;i<len;i++)
		printf("%d ",a[i]);
	printf("\n");
}
int main()
{
	srand(time(NULL));
	const int MAX=1000;
	int a[MAX];
	for(int i=0;i<MAX;i++)
		a[i]=rand();
	clock_t timebegin=clock();
	QuickSort(a,MAX);
	clock_t timeend=clock();
	//cout<<"优化排一千万个数耗时:\t"<<timeend-timebegin<<"ms"<<endl;
	print(a,MAX);
}


你可能感兴趣的:(C++,快速排序)