快速排序法事应用最广泛的排序算法之一,最佳情况下时间复杂度是 O(nlogn)。但是最坏情况下可能达到O(n^2)。说明快速排序达到最坏情况的原因。并提出改善方案并实现之。
改进方案:通过改变枢轴值得选取:
1 选择数组头数字
int part(int a[],int first,int last){
int pivote=a[first];
int low=first+1;
int high=last;
while(high>low){
//从左向右搜索比枢轴大的
while(low<=high&&a[low]<=pivote)low++;
//从右向左搜索比枢轴小的
while(low<=high&&a[high]>pivote) high--;
//直到第一个大于枢轴的左边和第一个小于枢轴的右边出现,交换
if(high>low){int t=a[low];a[low]=a[high];a[high]=t;}
}
//返回此次枢轴的坐标
while(high>first&&pivote<=a[high])high--;
if(pivote>a[high]){a[first]=a[high];a[high]=pivote;
return high;}
else return first;}
2 选择数组尾数字
//枢轴选择尾数字
int part1(int a[],int first,int last){
int pivote=a[last];
int low=first;
int high=last-1;
while(high>low){
//从左向右搜索比枢轴大的
while(low<=high&&a[low]<=pivote)low++;
//从右向左搜索比枢轴小的
while(low<=high&&a[high]>pivote) high--;
//直到第一个大于枢轴的左边和第一个小于枢轴的右边出现,交换
if(high>low){int t=a[low];a[low]=a[high];a[high]=t;}
}
//返回此次枢轴的坐标
while(low<last&&pivote>=a[low])low++;;
if(pivote<a[low]){a[last]=a[low];a[low]=pivote;
return low;}
else return last;}
3 选择数组中间数字
int part2(int a[],int first,int last){
//选取枢轴位置,取首元素,中间元素和末尾元素的中值作为枢轴
int low=first;
int high=last;
int mid=low + ((high - low) >> 1);//计算数组中间的元素下标
//将枢轴元素放在第一个位置
if(mid!=first){int t=a[mid];a[mid]=a[first];a[first]=t;}
return part(a,first,last);}
4 选择随机数作为枢轴
//选择随机数
int part4(int a[],int first,int last){
int low=first;
int high=last;
srand(time(0));
int index=rand()%(high-low)+low;//产生low-high之间随机数
if(index!=first){int t=a[index];a[index]=a[first];a[first]=t;}
return part(a,first,last);}
5 选择头数字尾数字和中间值的中位值
//选择头数字尾数字和中间值的中位值
int part3(int a[],int first,int last){
int low=first;
int high=last;
int mid=low + ((high - low) >> 1);
int index =mid1(first,last,mid);//求中位值
if(index!=first){int t=a[index];a[index]=a[first];a[first]=t;}
return part(a,first,last);}
最后:
//快速排序
void quicksort(int a[],int first,int last){
if(last>first){int pri=part4(a,first,last);
quicksort(a,first,pri-1);
quicksort(a,pri+1,last);}
}
void quicksort(int a[],int size){
quicksort(a,0,size-1);}