快速排序

参考:https://www.cnblogs.com/onepixel/articles/7674659.html

其他排序算法传送门:https://blog.csdn.net/jkdcoach/article/details/87442482

源码:https://github.com/sunrui849/sort

快速排序

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

1.1 算法描述

快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

  • 从数列中挑出一个元素,称为 “基准”(pivot);
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

1.2 动图演示

1.3特性

采用分治思想,理想情况下不断将数组分成两部分进行排序,平均时间复杂度为n*(log n),最坏为n*n

n*n:每一个选取的基准点都为当前区间最大或最小时,比较的次数即 (n-1) + (n-2) +...+1  = (n-1)*n/2 ,时间复杂度为n*n

n*(log n):比较的次数用 T表示

   T(n) = 2*T(n/2) + n

           =2*(2*T(n/4) + n/2) +n= 4*T(n/4) +2*n

           =4*(2*T(n/8) + n/4) + 2*n = 8*T(n/8) + 3*n...

当n=1时为0  T(1)=0,  结果为n*T(1)+(log n)n ,所以时间复杂度为n*(log n)

1.4代码实现

 /**
     * 从小到大
     * 快速排序
     * 初始化
     * @param arr
     * @return
     */
    public static int[] sort(int[] arr) {
        if (arr == null || arr.length == 0){
            return arr;
        }
        return quickSort(arr,0,arr.length-1);
    }

    /**
     * 递归排序两段数组
     * @param arr
     * @param left
     * @param right
     * @return
     */
    private static int[] quickSort(int[] arr, int left, int right) {
        if (left >= right) {
            return arr;
        }

        int middleIndex = sortMiddle(arr,left,right);//找个基准值并使基准值左侧小右侧大,返回基准值索引
        quickSort(arr,left,middleIndex-1);//排序左区间
        quickSort(arr,middleIndex+1,right);//排序右区间

        return arr;

    }

    /**
     * 排序区间数据,使选定值两侧分别为大或小
     * 左右闭区间
     * @param arr
     * @param left
     * @param right
     * @return
     */
    private static int sortMiddle(int[] arr,int left, int right){
        int sureValue = arr[left];//基准值
        int index = left +1;//这个标记右边为比选定值大的,左边为比选定值小的,相当于左区间上限+1
        for (int i = index; i <= right; i++){
            if (arr[i] < sureValue){//比基准值小则交换到左区间
                swap(arr,index,i);
                index++;//左区间上限+1
            }
        }
        swap(arr,left,index-1);//使基准值与左区间上限替换
        return index-1;
    }

    /**
     * 交换位置
     * @param arr
     * @param i
     * @param j
     */
    private static void swap(int[] arr,int i,int j) {
        int flag = arr[i];
        arr[i] = arr[j];
        arr[j] = flag;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值