算法笔记-快速排序(Quick Sort)之Duplicate Keys

本文介绍了在快速排序中遇到重复元素(重复键)时如何使用3-way partitioning方法进行处理,确保排序正确。通过一系列步骤展示了算法如何区分小于、等于和大于pivot的元素,并给出了Java实现的上下文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:
当数组中有很多重复的元素(Dupicate Keys)时,采用3-way partitioning,即把array分成三部分,一部分是小于duplicate keys的,一部分是等于duplicate keys,还有一部分是大于duplicate keys。当然,一轮partition只能让一种duplicate keys归位,如果其他数字也有duplicate的情况,则需要进行下一轮partition。

Goal:
Goal

算法思路:

  • a[lo]作为pivot
  • 从左向右扫描i(其实一直都是a[i]和pivot在比较)
    • (a[i] < pivot): 交换a[lt]和a[i]; lt, i同时加1。
    • (a[i] > pivot): 交换a[gt]和a[i]; gt减1。(i不变,因为交换后的i指向的元素还没有和a[lt]比较)
    • (a[i] == pivot): i加1。
      invariant

demo:
1. 初始化。
in
2. i+1,这一轮partitioning element是P;lt->P, i->A
2
3. A<<P, 故a[lt]和a[i]交换,且lt, i同时+1;lt->P, i->B (lt一直指向partitioning element)
3
4. B<<P, 故a[lt]和a[i]交换,且lt, i同时+1;lt->P, i->X
4
5. X>>P, 故a[gt]和a[i]交换,且gt-1;i->Z, gt->Y(gt已经减1了)
5
6. Z>P, 故a[gt]和a[i]交换,且gt-1;i->Y, gt->C
6
7. Y>>P, 故a[gt]和a[i]交换,且gt-1;i->C, gt->P
7
8. C<P, 故a[lt]和a[i]交换,且lt, i同时+1;lt->P, i->W
8
9. W>>P, 故a[gt]和a[i]交换,且gt-1;i->P, gt->D
9
10. P=P, 故i++; lt->P, i->P
10
11. P=P, 故i++; lt->P, i->P
11
12. P=P, 故i++; lt->, i->V
12
13. V>P, 故 a[gt]和a[i]交换,且gt-1;i->D, gt->P
13
14. D<<P, 故a[lt]和a[i]交换,且lt, i同时+1;lt->P, i->P [此时pointers cross说明所有数都被scan过了]
14

Language: Java
a

private static void sort(Comparable[] a, int lo, int hi)
{
    if (hi <= lo) return;
    int lt = lo, gt = hi;
    Comparable v = a[lo];
    int i = lo;
    while(i <= gt)
    {
        int cmp = a[i].compareTo(v);
        if(cmp < 0)
            swap(a[lt++], a[i++]);
        else if(cmp > 0) 
            swap(a[i], a[gt--]);
        else i++;
}

sort(a, lo, lt - 1);
sort(a, gt + 1, hi);
}

图片来源:Coursera
参考资料:Algorothm 4th

Happy Coding!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值