我的算法笔记—快速排序

算法介绍

由C.A.R.Hoare在1962年提出,因为此算法而获得图灵奖。它是一种递归算法,核心思想是:先找出一个数的应该在的位置,将数列分为左右两部分,左右两部分分别进行排序。

图片示例

我们先找到 K 的位置,i 指针先向后移动,所指元素如果比K大,就停止,此时再由 j 由队尾向前遍历,如果 j 指向元素比K小,j 停止移动,此时将 i 和 j 指向元素对调。
比如:

此时 i 指向元素R比 K 大,j 指向元素C比K小 ,对调R,C。

此时 i j 根据上述规则 继续移动,一直到 指针 j 超过了i ,K 和 j 对调

此时K已经在位置上了,将数列分为左右两边,左右再进行递归排序

实现代码

//主方法
private static void sort(Comparable[] a, int lo, int hi) {
        if (lo >= hi) {
            return;
        }
        int j = partition(a, lo, hi);
        sort(a, 0, j - 1);
        sort(a, j + 1, hi);
    }

private static int partition(Comparable[] a, int lo, int hi) {
        int i = lo ;
        int j = hi+1;
//a[lo]即为第一个元素,先将它的位置找到
        while (true){
// 找到 i ,i 小于 a[lo]的话,继续移动
            while (less(a[++i],a[lo])){
                if(i == hi){
                    break;
                }
            }
// j 也类似
            while (less(a[lo],a[--j])){
                if(j==lo){
                    break;
                }
            }
// 两指针擦肩而过的话,就跳出循环
            if(i>=j){
                break;
            }
// 交换 i和j
            change(a,i,j);
        }
// 交换 lo和j
        change(a,lo,j);
        return j;
    }

复杂度推导

假设 Cn 为快速排序N个数需要比较的次数。
找到第一个数所在位置,我们需要比较 N+1次。指针 i 和 j 每移动一次就需要比较一次,一共是 N-1次, 加上相遇比较一次 ,擦肩而过还需要比较一次,所以是N+1次。
这个数会把数组分割成各种情况,会分割成(1,n-1),(2,n-2),(3,n-3).......(n-1,1)各种情况,所以Cn的表达式如下:


平均复杂度为1.39NlgN

缺点与不足

 1. 为了保证性能,快速排序前一定要打乱数组顺序,正序下,快排复杂度需要1/2 
    乘以n的二次方
    

 2. 如果数组存在大量相同的数,性能也是平方级的
 
 

第一次写博客,这是我的理解,如果有误请指出,我会立即纠正,谢谢

你可能感兴趣的:(java,算法,算法复杂度)