基本排序算法之快速排序

本文深入解析了快速排序这一高效排序算法的原理与实现。快速排序采用分治策略,通过递归方式将数组分为两部分并独立排序。文章详细介绍了partition()方法的作用及其实现,以及如何通过切分策略使数组满足特定条件,实现元素的有效排序。此外,还讨论了算法的改进措施,如在处理小数组时切换到插入排序,以及介绍了一种更高效的三向切分的快速排序算法。

快速排序是一种分治的排序算法。它将一个数组分为两个数组,将两部分独立地排序。

快速排序递归地将子数组a[lo..hi]排序,先用partition()方法将a[j]放到一个合适的位置,然后再用递归调用将其他位置的元素排序。

该方法的关键在于切分,这个过程使得数组满足下面三个条件:

1.对于某个j,a[j]已经排定;

2.a[lo]到a[j - 1]中的所有元素都不大于a[j];

3.a[j + 1]到a[hi]的所有元素都不小于a[j]。

切分的一般策略是先随意的取a[lo]作为切分元素,即那个将会被排定的元素,然后我们从数组的左端开始向右扫描直到找到一个大于等于它的元素。再从数组的右端开始向左扫描直到找到一个小于等于它的元素

具体实现:

public static int partition(Comparable[] a, int lo, int hi){
    Comparable v = a[lo];
    int i = lo;
    int j = hi + 1;
    while (true){
        while(less(a[++i], v)){
            if(i == hi){
                break;
            }
        }
        while(less(v, a[--j])){
            if(j == lo){
                break;
            }
        }
        if(j <= i){
            break;
        }
        Example.exch(a, j , i);
    }
    Example.exch(a, j, lo);
    return j;
}

public static void sort(Comparable[] a, int lo, int hi){
    if(hi <= lo){
        return;
    }
    int j = partition(a, lo, hi);
    sort(a, lo , j - 1);
    sort(a, j + 1, hi);
}

快速排序算法改进

1.切换到插入排序

    (1)对于小数组,快速排序比插入排序慢;

    (2)因为递归,快速排序的sort()方法在小数组中也会调用自己。

    因此,在排序小数组时应该切换到插入排序。

三向切分的快速排序

    public static void threeWaySort(Comparable[] a, int lo, int hi){
        if(hi <= lo){
            return;
        }
        int lt = lo, i = lo + 1, gt = hi;
        Comparable v = a[lo];
        while(i <= gt){
            int cmp = a[i].compareTo(v);
            if(cmp > 0){
                Example.exch(a, i, gt--);
            }else if(cmp < 0){
                Example.exch(a, i++, lt++);
            }else{
                i++;
            }
        }//现在a[lo..lt-1] < v = a[lt..gt] < a[gt + 1..hi]
        sort(a, lo, lt - 1);
        sort(a, gt + 1, hi);
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值