快速排序(经典快排以及随机快排)

Posted pipipi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序(经典快排以及随机快排)相关的知识,希望对你有一定的参考价值。

快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
首先来了解一下经典快排:
技术分享图片

 

其中就小于等于的区域可以优化一下,小于的放小于区域,等于的放等于区域,大于的放大于区域。可以利用荷兰国旗问题

荷兰国旗问题:

给定一个数组arr,和一个数num,请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。

这就是荷兰国旗问题,大致过程如图:

技术分享图片

代码如下

public class Code5_NetherlandsFlag {
    
    public static int[] partition(int[] arr, int l, int r, int num) {
        int less = l - 1;
        int more = r + 1;
        while (l < more) {
            if (arr[l] < num) {
                swap(arr, ++less, l++);
            } else if (arr[l] > num) {
                swap(arr, --more, l);
            } else {
                l++;
            }
        }
        return new int[] { less + 1, more - 1 };
    }
    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}

优化后快排代码为:

    public static void quickSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        quickSort(arr, 0, arr.length - 1);
    }

    public static void quickSort(int[] arr, int l, int r) {
        if (l < r) {
            swap(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int[] p = partition(arr, l, r);
            quickSort(arr, l, p[0] - 1);
            quickSort(arr, p[1] + 1, r);
        }
    }

    public static int[] partition(int[] arr, int l, int r) {
        int less = l - 1;
        int more = r;
        while (l < more) {
            if (arr[l] < arr[r]) {
                swap(arr, ++less, l++);
            } else if (arr[l] > arr[r]) {
                swap(arr, --more, l);
            } else {
                l++;
            }
        }
        swap(arr, more, r);
        return new int[] { less + 1, more };
    }

    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

其中swap(arr, l + (int) (Math.random() * (r - l + 1)), r);这一句是为了将快排受数据状态的影响变成一个概率性的,随机的

以上是关于快速排序(经典快排以及随机快排)的主要内容,如果未能解决你的问题,请参考以下文章

排序(重点介绍快速排序的各种场景, 堆排序的数组空洞)

排序(重点介绍快速排序的各种场景, 堆排序的数组空洞)

排序(重点介绍快速排序的各种场景, 堆排序的数组空洞)

JavaScript实现快速排序算法

8种面试经典!排序详解--选择,插入,希尔,冒泡,堆排,3种快排,快排非递归,归并,归并非递归,计数(图+C语言代码+时间复杂度)

随机快速排序的细节和复杂度分析