快速排序

Posted

tags:

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


简易代码
排序的全过程
[49, 38, 65, 97, 76, 13, 27, 49]--从【右】端开始比较,如果【右】端的元素【小】于基准元素,则交换,所以会把【右】端的27和基准元素49交换
[27, 38, 65, 97, 76, 13, 49, 49]--从【左】端开始比较,如果【左】端的元素【大】于基准元素,则交换,所以会把【左】端的65和基准元素49交换
[27, 38, 49, 97, 76, 13, 65, 49]--从【右】端开始比较,如果【右】端的元素【小】于基准元素,则交换,所以会把【右】端的13和基准元素49交换
[27, 38, 13, 97, 76, 49, 65, 49]--从【左】端开始比较,如果【左】端的元素【大】于基准元素,则交换,所以会把【左】端的97和基准元素49交换
第一趟交换完毕,然后会将原数组分割为两个数组,其中基准元素49已经是在正确的位置了

先排序左半部分
[27, 38, 1349, 76, 97, 65, 49]-从【右】端开始比较,如果【右】端的元素【小】于基准元素,则交换,所以会把【右】端的13和基准元素27交换
[13, 382749, 76, 97, 65, 49]-从【左】端开始比较,如果【左】端的元素【大】于基准元素,则交换,所以会把【左】端的38和基准元素27交换
左半部分已经完成排序,再排序右半部分
[13, 27, 38, 4976, 97, 65, 49]--从【右】端开始比较,如果【右】端的元素【小】于基准元素,则交换,所以会把【右】端的49和基准元素76交换
[13, 27, 38, 49, 49, 97, 65, 76]--从【左】端开始比较,如果【左】端的元素【大】于基准元素,则交换,所以会把【左】端的97和基准元素76交换
[13, 27, 38, 49, 49, 7665, 97]--从【右】端开始比较,如果【右】端的元素【小】于基准元素,则交换,所以会把【右】端的65和基准元素76交换
[13, 27, 38, 49, 49, 65, 76, 97]
左右半部分都已【递归】排序完毕

public class Test {
    public static void main(String[] args) throws Exception {
        int[] arr = { 49, 38, 65, 97, 76, 13, 27, 49 };
        System.out.println(Arrays.toString(arr));
        qsort(arr, 0, arr.length - 1);
    }
    /**
     * 快速排序<br>冒泡排序的升级版,现在用的最多的排序方法<br>不稳定排序算法<br>
     * 时间复杂度:最好:O(nlogn),最坏:O(n^2)  <br>空间复杂度:O(logn)  
     * @param arr    要排序的数组
     * @param low    对此数组指定的范围排序
     * @param high    对此数组指定的范围排序
     */
    public static void qsort(int[] arr, int low, int high) {
        if (low < high) {
            int pivot = partition(arr, low, high);//将表一分为二
            qsort(arr, low, pivot);//【递归】对低子表【递归】排序
            qsort(arr, pivot + 1, high);//递归对高子表递归排序
        }
    }
    /**
     * 对数组进行分割
     */
    private static int partition(int[] arr, int low, int high) {
        int pivotkey = arr[low];//选择一个【基准元素】,通常选择第一个元素或者最后一个元素
        while (low < high) {//从表的两端【交替】地向中间扫描
            while (low < high && arr[high] >= pivotkey) {
                high--;
            }
            swap(arr, low, high);//将比基准元素小的交换到低端
            while (low < high && arr[low] <= pivotkey) {
                low++;
            }
            swap(arr, low, high);//将比基准元素大的交换到高端
        }
        return low;//此时基准元素在其排好序后的正确位置
    }
    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
        System.out.println(Arrays.toString(arr));
    }
}

原理
基本思想: 1)选择一个基准元素,通常选择第一个元素或者最后一个元素, 2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的元素值比基准值大。 3)此时基准元素在其排好序后的正确位置 4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
一趟排序的过程:
技术分享

排序全过程:
技术分享

分析: 快速排序是通常被认为在同数量级(O(nlog2n))的排序方法中平均性能最好的。但若初始序列按关键码有序或基本有序时,快排序反而蜕化为冒泡排序。为改进之,通常以“三者取中法”来选取基准记录,即将排序区间的两个端点与中点三个记录关键码居中的调整为支点记录
快速排序是一个不稳定的排序方法。













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

算法排序之堆排序

前端开发工具vscode如何快速生成代码片段

前端开发工具vscode如何快速生成代码片段

如何使用sublime代码片段快速输入PHP头部版本声明

代码片段如何使用CSS来快速定义多彩光标

vs2003:快速片段工具