基本排序算法 之五 ——快速排序

 

 


基本排序算法总结与对比 之五  ——快速排序 


1、快速排序  二路双向快排 版本

       首先列出教科书上最普遍的版本:二路快排,准确的说 应该叫 二路双向快排。笔者认为这个应该是效率最为均衡的版本,网络上也流传着 三路快排,但是 三路快排 仅仅是在序列中存在大量重复元素时,才会发挥出其优势。在对 随机序列 和 近有序序列排序时,效率均低于 二路双向快排

       二路双向快排过程如下图:从左右两端开始检测元素,左边 ≥ 基准元素(基准元素一般选首元素) 的元素 与 右边 ≤ 基准元素 的元素交换,直至两边检查的下标(左 i,右 j)相遇(i ≥ j)则停止检查;然后基准元素与 检查下标指向的较小元素(即 j 指向的元素)交换(这是因为“基准”元素选在序列首位,而且要求升序排列)。此时,序列将以“基准”元素为间隔,分为 ≤“基准”元素 与 ≥“基准”元素 的两部分,这一过程称为Partition。使用分治算法,重复Partition过程直至序列有序。

       

       以下是 二路双向快排 的实现代码:(上图中 i 为代码中 _lo ,j 为 代码中 _hi

template<typename T>
void quickSort(T arr[], int lo, int hi)
{
    if(hi - lo < 2) return;
    
    //交换序列 中间元素 与 首元素,使中间元素为“基准”元素
    T temp = arr[(lo + hi) >> 1];
    arr[(lo + hi) >> 1] = arr[lo]
    arr[lo] = temp;

    int _lo = lo, _hi = hi;
    T key = arr[lo];

    while(true)
    {
        while(arr[++_lo] < key && _lo < hi);  //向右找≥key的元素
        while(arr[--_hi] > key && _hi > lo);  //向左找≤key的元素
        if(_lo >= _hi) break;  //_lo与_hi相交时结束循环
        temp = arr[_lo];  arr[_lo] = arr[_hi]; arr[_hi] = temp;  //交换_lo,_hi对应的值
    } 
    temp = arr[_hi];  arr[_hi] = key;  arr[lo] = temp;  //“基准”值与_hi对应值交换
    /*  为什么与 _hi 对应的值交换呢?  
           1、基于升序排列
           2、把基准元素放到了前面
          条件1,2 决定了 基准元素的位置 应该存放比基准元素 小 或者 等 的元素,
          而 _hi 只有遇到 <= 基准元素 的元素时才会停下! 即 _hi 最终指向<= 基准元素 的元素
    */
    quickSort(arr, lo, _hi);
    quickSort(arr, _hi + 1, hi);
}

       快速排序是不稳定的排序方法。另外快排(未优化的快排)在大量重复数据和基本有序数据排序时效率较低。

       对于大量数据重复的排序,可以采取三路快排的方式。

       对于基本有序数据,则可以随机化基准元素(或者基准取中间,基准三取中)提高排序效率。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值