排序算法学习——快速排序

来源:互联网 发布:淘宝卖家支付宝限额 编辑:程序博客网 时间:2024/06/11 01:28

快速排序:
作为冒泡排序的一种改进;通过设置一个标志值(通常为数组第一个元素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变量监督两个子序列的起泡情况,如果有起泡,则需再排序,无起泡操作无需再进行排序

0 0