针对重复键值的3路快速排序算法

  针对待排序列中农存在大量重复键值的情况,上一节讲了一种对快排算法的优化,代码如下:

template<typename T>
int __patition(T arr[], int l, int r)
{
    swap(arr[l], arr[rand() % (r - l + 1) + l]);
    T v = arr[l];
    int i = l + 1, j = r;
    while(true)
    {
        while(i <= r && arr[i] < v)
        {
            i++;
        }
        while(j >= l + 1 && arr[j] > v)
        {
            j--;
        }
        if(i > j)
        {
            break;
        }
        swap(arr[i++],arr[j--]);
    }
    swap(arr[j], arr[l]);
    return j;
}

template<typename T>
void __quickSort(T arr[], int l, int r)
{
    if(l >= r)
    {
        return;
    }
    else
    {
        int p = __patition(arr, l, r);
        __quickSort(arr, l, p - 1);
        __quickSort(arr, p + 1, r);
    }
}

template<typename T>
void quickSort(T arr[], int n)
{
    srand(time(0));
    __quickSort(arr, 0, n - 1);
}
  实际上还存在一种针对重复键值的经典优化快排算法,称为3路快速排序算法,这种排序算法相比上一节的优化效率更高,3路快排将待排序列分为3部分:<v、==v、>v,则进行递归时,对==v的部分就不用考虑,只需考虑对<v和>v部分进行递归排序,如图所示:


   若 i 指向的元素<v,则交换arr[lt+1]和arr[i],然后i++,若 i 指向的元素==v,则直接i++,若 i 指向的元素>v,则交换arr[i]和arr[gt-1],此时不需要维护 i ,只需要将gt--即可,整个过程就是这样的,最后的结果如下图所示:


  最后将arr[l]和arr[lt交换]。


  接下来递归只针对<v和>v的部分进行递归即可,可以看出,对于含有很多重复键值的序列来说,可以省去对==v部分进行下一层递归操作,这将节省很多时间。

  3路快速排序算法的C++实现如下,我们将之前讲的2种快排和3路快排进行时间性能上的比较:

SortTestHelper.h文件(包含辅助函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值