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

本文详细介绍了快速排序算法的实现原理及具体代码实现。通过对比不同教材中的快排算法,选取了一种简洁且能有效处理极端情况的方法。文章还深入探讨了快速排序的分区过程,并提供了完整的Java实现。

看了教科书上的快排,又对比了“Algorithm 4th”里的快排,感觉后者更加简洁清晰,而且成功cover极端情况,故决定采用“Algorithm 4th”里面的快排代码。
算法思路:
一轮 QuickSort Partition有两个phase:
phase 1:重复步骤直到i, j指针交叉

  • 从左向右扫描i指针(只要满足a[i]<a[lo],当然,一开始把a[lo]作为pivot了)
  • 从右向左扫描j指针(只要满足a[j]>a[lo]

phase 2: 当i, j交叉时

  • 交换a[lo]a[j](注意!不是交换a[i]!因为此时a[j]能保证是小于等于a[lo]的。)

以上一轮过程就是partition。

Language: Java
Partition过程:(一轮归位)

private static int partition(Comparable[] a, int lo, int hi)
{
    int i = lo, j = hi+1;//之所以是hi+1是因为下面是--j,j要先减1然后再对比
    while(true)
    {
        while(less(a[++i], a[lo]))
            if(i == hi) break;
        while(less(a[lo], a[--j]))
            if(j == lo) break;

        if(i >= j)break;检测i,j是否交叉
        swap(a[i], a[j]);//如果i,j尚未相遇,则交换
}

swap(a[lo], a[j])//注意是和a[j]不是a[i]交换!
return j;//返回被正确归位的元素位置
}

QuickSort完整过程:

public class Quick
{
    private static int partition(Comparable[] a, int lo, int hi)
    {/*见上面代码*/}

    public static void sort(Comparable[] a)
    {
        StdRandom.shuffle(a);//Shuffle是很重要的
        sort(a,0,a.length-1);//正式开始排序
}

    private static void sort(Comparable[] a, int lo, int hi)
    {
        if(hi <= lo) return;
        int j = partition(a,lo,hi);//j是已归位位置
        sort(a,lo,j-1);
        sort(a,j+1,hi);
}
}

QuickSort 细节:

  • QuickSort比MergeSort的优点在于快排的partition是in-place的,不会占用多余空间。
  • 判断指针是否交叉是很关键的一个环节
  • 越界判断:i==hi是必须的,j==lo是redundant的。
  • Shuffling is needed for performance guarantee.
  • Equal Keys. 当有待排序数列中有重复元素时,在和pivot相同的元素位置上停下来会更好。(尽管counter-intuitive,见下一节笔记。)
  • Best case: O(NlogN)O(NlogN),有点像二分法;Worst case: O(N2)O(N2)

不仅快排是面试常考算法,其中的Partition也是Leetcode常用代码。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值