快速排序法 —— 个人解读

快速排序法的原理

每次从当前考虑的数组中选择一个元素,以这个元素为基点,之后将这个元素挪到排好序的时候应该所在的位置。

这样就有一个性质,这个元素之前的所有元素小于它,之后的所有元素大于它。然后分别对这两边进行快速排序,逐渐递归下去,完成整个排序过程。

Partition

更加抽象的说,对于数组的一个区间,如果我们选定了一个标定点v,如何把v放到正确的位置,使得v前面的元素都是小于它,v后面的元素都是大于它。那么这样的一个过程被称为partition。(笔者画图如下)
在这里插入图片描述

如果允许开辟额外的空间,是非常容易解决这个问题的。只需要开辟两个空间left和right,left存储v(4)左侧的值,rigth存储v(4)右侧的值,然后遍历一遍数组中所有的值(标定点不需要遍历)。
笔者在这里画了个图如下:
在这里插入图片描述
最后整理下数组,就排成如下这样了。(图可能画的有点歪,不要在乎这些细节)在这里插入图片描述

在这里插入图片描述
这样一来我们已经完成了partition要做的事情,但这种使用了额外空间,非原地排序。
但对于快速排序来说,之所以快是不需要申请额外空间的内存操作。那么如何原地进行partition?

下面笔者介绍下原地完成partition的思路:
假设对如下数组区间进行一个partition过程
在这里插入图片描述
依然使用数组区间中第一个元素v(l位置)作为标定点,之后逐渐遍历右边所有没被访问过的元素,在遍历的过程中,我们将逐渐整理让数组一部分是小于v,另外一部分是大于v的元素,用 j 索引记录这个分界点,当前访问的元素用 i 来标记。
在这里插入图片描述

如果当前访问的元素e大于v则:
在这里插入图片描述

如果当前访问的元素e小于v则:
在这里插入图片描述
对整个数组进行一次遍历后整个数组就划分成三部分了:
在这里插入图片描述

最后将 l 位置和 j 位置进行一次交换如下
在这里插入图片描述

第一版快速排序法

import java.util.Arrays;
/**
 * 描述     快速排序法
 *
 * @author lixinzhen
 * @create 2021/9/30 10:10
 */
public class QuickSort {
    private QuickSort() {
    }

    public static <E extends Comparable<E>> void sort(E[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    private static <E extends Comparable<E>> void sort(E[] arr, int l, int r) {
        if (l >= r) return;
        int p = partition(arr, l, r);
        sort(arr, l, p - 1);
        sort(arr, p + 1, r);
    }

    private static <E extends Comparable<E>> int partition(E[] arr, int l, int r) {
        //arr[l+1..j] < v ; arr[j+1..i] > v
        int j = l;//标定点所在位置
        for (int i = l + 1; i <= r; i++)
            if (arr[i].compareTo(arr[l]) < 0) {
                j++;
                Swap(arr, i, j);
            }
        Swap(arr, l, j);
        return j;//返回标定点所在位置的索引
    }

    private static <E extends Comparable<E>> void Swap(E[] arr, int i, int j) {
        E t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

    public static void main(String[] args) {
        Integer[] arr = {4, 6, 2, 3, 1, 5, 7, 8};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

在这里插入图片描述
第一版快速排序时间复杂度是O(n),如果是一个完全有序的数组,则时间复杂度为O(n^2)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

༄༊心灵骇客༣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值