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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值