快速排序:
作为冒泡排序的一种改进;通过设置一个标志值(通常为数组第一个元素pivot),一次快排将数组分成两个部分,一部分(升序–前一部分)小于标志值pivot,另一部分大于标志值(升序–后面部分),各部分内部可以是(通常也是)无序的。通过递归地调用这样的排序,使得最终数组所有的元素有序。一次具体的快排设计如下:
#define Datatype float //针对不同的数据类型均可
void swap(Datatype *a, Datatype *b) //交换元素
{
Datatype tmp = *a;
*a = *b;
*b = tmp;
}
/******一次划分/快排操作********/
int fastsort_once(Datatype *L,int low,int high)
{
Datatype tmp=L[low];
/********************************/
while(low<high)
{
while((low<high)&&(L[high]>=tmp)) --high;
//从后往前找第一个小于privot的值
swap(&L[low], &L[high]);
//将比privot小的记录换至低端
while((low<high)&&(L[low]<=tmp)) ++low;
//从前往后找第一个大于于privot的值
swap(&L[low], &L[high]);
//将比privot大的记录换至高端
}
/***************************
一种改进的方法:将privot值先暂存起来,一趟快排确定privot的
位置(返回的low值),只将L[low]或L[high]做单向移动。一趟快
排结束,将privot的值记录在正确的位置L(low)上,对应代码:
while(low<high)
{
while((low<high)&&(L[high]>=tmp)) --high;
//从后往前找第一个小于privot的值
L[low]=L[high];
//将比privot小的记录移至低端
while((low<high)&&(L[low]<=tmp)) ++low;
//从前往后找第一个大于于privot的值
L[high]=L[low];
//将比privot大的记录移至高端
}
L[low]=tmp;
***************************/
return low;
}
void fastsort_all(Datatype *L,int low,int high)
{
if(low<high)
{
int mid=fastsort_once(L,low,high);
fastsort_all(L,low,mid-1);
fastsort_all(L,mid+1,high);
}
}
int main()
{
Datatype privot=0;
Datatype number[20];
for(int i=0;i<20;i++)
{
cin>>number[i];
}
for(int i=0;i<20;i++)
cout<<number[i]<<" ";
fastsort_all(number,0,19);
for(int i=0;i<20;i++)
cout<<number[i]<<" ";
cout<<endl;
system("pause");
return 0;
}
注意上面两种方法中:“换”与“移”的区别。
注意到:通常情况下,快速排序的时间复杂度为O(NlogN),若初始记录序列按关键字privot基本有序,则其退化成冒泡排序,时间复杂度变为O(N^2),这基本上是最坏的情况了,我们可以通过改进privot的值来改进算法,通过在L[low],L[high],L[(low+high)/2]中选择中间的值即“三者取中”的方式来进行privot值的确定。如何将已按privot有序的序列的复杂度降到O(n),可通过对修改一次划分操作。确定了privot以后,对high减1、low增1的同时,进行起泡操作,通过两个bool变量监督两个子序列的起泡情况,如果有起泡,则需再排序,无起泡操作无需再进行排序
2731

被折叠的 条评论
为什么被折叠?



