三路快速排序

本文介绍快速排序的基本原理及其两种优化方案:一种通过调整分区策略减少退化情况的发生;另一种为三路快速排序,它能更高效地处理含有大量重复元素的数组。

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

快速排序
普通快速排序在多数值==v的情况下,表现不佳。原因在于part左右分配不均,引发退化。优化后,会将==v部分part左右平分,消除影响,但仍然不是最佳之选。

/**
 * 快速排序优化
 */
public class QuickSortFast {

    public static void sort(Integer[] arr){
        Integer n = arr.length;
        quickSort(arr,0,n-1);
    }

    private static void quickSort(Integer[] arr, int l, int r) {
        if(r-l<=15){
            InsertionSort.sort2(arr,l,r);
            return;
        }
        int p = partition(arr,l,r);
        quickSort(arr,l,p-1);
        quickSort(arr,p+1,r);
    }

    // 返回p,使得arr[l...p-1]<arr[p]; arr[p+1...r]>arr[p]
    private static int partition(Integer[] arr, int l, int r) {
        // 随机选取标定元素
        Tlt.exch(arr,l,StdRandom.uniform(l, r));
        Integer v = arr[l];
        // arr[l+1...i) <= v; arr[j...r] >= v
        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;
            Tlt.exch(arr,i,j);// 这种情况在arr[i]=v=arr[j]的情况下也会交换。但是好在将等于v的数据在part两部分平分了,阻止退化成on^2。
            i++;
            j--;
        }
        Tlt.exch(arr,l,j);
        return j;
    }

    public static void main(String[] args) {
        Integer[] random = Tlt.random(100000, 0, 100000);
        sort(random);
        Tlt.show(random);
    }
}

三路快速排序实现

/**
 * 三路快速排序
 */
public class QuickSort3Ways {

    public static void sort(Integer[] arr){
        Integer n = arr.length;
        quickSort3Ways(arr,0,n-1);
    }

    private static void quickSort3Ways(Integer[] arr, int l, int r) {
        if(r-l<=15){
            InsertionSort.sort2(arr,l,r);
            return;
        }
        Tlt.exch(arr,l,StdRandom.uniform(l, r));
        Integer v = arr[l];

        int lt= l;      // arr[l+1...lt] < v
        int gt = r+1;   // arr[gt...r] > v
        int i = l+1;    // arr[lt+1...i] == v
        while(i<gt){
            if(arr[i] < v){
                Tlt.exch(arr,i,lt+1);
                lt++;
                i++;
            }else if(arr[i]>v){
                Tlt.exch(arr,i,gt-1);
                gt--;

            }else{
                i++;
            }
        }
        Tlt.exch(arr,l,lt);
        quickSort3Ways(arr,l,lt-1);//不考虑==v部分
        quickSort3Ways(arr,gt,r);//不考虑==v部分
    }

    public static void main(String[] args) {
        Integer[] random = Tlt.random(100000, 0, 100000);
        sort(random);
        Tlt.show(random);
    }
}

void quickSort3Ways(Integer[] arr, int l, int r)

三路排序将数组分成三个部分 >v,==v,等于v。遍历元素

当e==v
这里写图片描述

当e<v
这里写图片描述

当e>v
这里写图片描述
交换之后,i虽然不需要变大,但是gt需要减1维护>v的结构

初始化
这里写图片描述

当i==gt的时候遍历结束
这里写图片描述

交换标准元素v
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值