Java快排【代码极短】【递归 +分治】

1、快速排序的原理

选择一个关键值作为基准值,比基准值小的都在左边序列(仍是无序的),比基准值大的都在右边序列(也是无序的),基准值的选取:一般为第一个元素。
第一次循环:先从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置。如果没有就继续比较下一个,直到找到第一个比基准值小的值才交换。 找到这个值之后,就从前往后开始比较,如果有比基准值大的,交换位置,没有就继续比较下一个,直到找到第一个比基准值大的值才交换。第一次 循环结束条件 :从前往后的索引指针>从后往前的索引指针,然后递归排序前后两段‘子组’。

2、动图实现快排

在这里插入图片描述

在这里插入图片描述

3、具体实现代码:

import java.util.Arrays;
public class QuickSortDemo {
    public static void main(String[] args) {
        
        int[] num = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
        System.out.println("未排序:" + Arrays.toString(num));
        quickSort(num, 0, num.length - 1);
        System.out.println("排序后:" + Arrays.toString(num));
    }

    public static void quickSort(int[] arr, int start, int end) {
        if (arr == null || start >= end) return;
        int i = start, j = end;
        int pivotKey = arr[start]; // 用子表的第一个记录做基准
        // 从表的两端交替向中间扫描
        while (i < j) {
            // 顺序很重要,要先从右边开始找
            while (i < j && arr[j] >= pivotKey) j--;
            if (i < j) arr[i++] = arr[j];             //用比基准小的记录替换低位记录
            while (i < j && arr[i] <= pivotKey) i++;
            if (i < j) arr[j--] = arr[i];             // 用比基准大的记录替换高位记录
        }
        arr[i] = pivotKey;                           // 将基准数值替换回 arr[i]
        quickSort(arr, start, i - 1);           // 递归排序比开始时基准数低的'子数组'
        quickSort(arr, i + 1, end);            // 递归排序比开始时基准数高的'子数组'
    }
}

排序结果:
在这里插入图片描述

4、复杂度分析:

(1)时间复杂度

① 最好和平均时间复杂度

最好情况是指选择的基准关键字为待排序的记录的中间值。此时进行比较次数总共为 nlogn,所以最好情况下快速排序的时间复杂度为O(nlogn)。
快速排序的平均时间复杂度为O(nlogn)。
在所有平均时间复杂度为O(nlogn)的算法中,快速排序的平均性能是最好的。

② 最坏时间复杂度

最坏情况是指每次区间划分的结果都是基准关键字的左边(或右边)序列为空,而另一边区间中的记录仅比排序前少了一项,即选择的关键字是待排序记录的最小值或最大值。最坏情况下快速排序的时间复杂度为O(n^2)。

(2)空间复杂度

快速排序的过程中需要一个栈空间来实现递归。最好情况递归树的深度为log2n,其空间复杂度也就是O(nlogn);平均情况空间复杂度为O(nlogn);最坏情况下,需要进行 n-1次递归,其空间复杂度为O(n)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值