Sorting 排序算法: Quick Sort 快速排序

news/2024/5/20 0:36:04 标签: 快速排序, java, 排序算法, 算法

Sorting 算法>排序算法: Quick Sort 快速排序

文章目錄

简介

快速排序作为最常被应用的算法>排序算法,因为其拥有最好的平均时间效率,同时只用了常数的额外空间,所以受到大多数应用的青睐。

参考

正文

算法思想原理

输入

java">/* 传入参数 */
int[] A // 原数组(可以是任何类型的数据,这边使用 int 类型为示例)

/* 限制 */
int n // 数组长度

算法思想

快速排序也和归并排序一样采用了分治的思想,但是与归并不同的是划分(partition)阶段并不只是单纯的分成两半,而是选定一个基准值(pivot),将整个数组划分成"比 pivot 小"和"比 pivot 大"的两半,然后再分别排序。分类时的交换使得合并(merge)阶段只需要花费常数的时间代价即可完成

  • 动图

算法流程

伪代码(参考:算法导论)

Quick-Sort(A)
    Quick-Sort(A, 0, A.length)

Quick-Sort(A, l, r)
    if l < r
        q = partition(A, l, r)
        Quick-Sort(A, l, q - 1)
        Quick-Sort(A, q + 1, r)

Partition(A, l, r)
    pivot = A[r]
    i = l - 1
    for j = l to r - 1
        if A[j] <= pivot
            i = i + 1
            exchange A[i] and A[j]
    exchange A[i + 1] and A[r]
    return i + 1

与归并排序相同,分治算法使用左右界作为参数,以 [0 … A.length - 1] 区间为起始。当子数组长度大于 1 时(l < r),就进行划分,然后再分别对两个子数组进行排序。
在划分阶段,直接选取最右边的数作为基准(pivot),i 指向左子数组(比 pivot 小)的末尾,j 遍历一遍数组,遇到比 pivot 小的数就交换到 i 位置。循环结束时将第 i + 1 个数也就是第一个大于 pivot 的值与 pivot 交换,就相当于划分出以 i + 1 位置为界:i + 1 以左的都小于(等于) pivot,以右的都大于 pivot。如此递归知道数组长度为 1。

算法复杂度分析

先说结论:

  1. 时间复杂度:最坏 O(n2) / 平均 O(nlogn)
  2. 空间复杂度:O(1)
  3. 原址排序
  4. 不稳定的
  • 时间复杂度:最坏 O(n2) / 平均 O(nlogn)

在最坏的情况下每次划分都将所有元素划分到同一边,这时时间复杂度就接近 O(n2),然而这种情况是极少出现的,只要中间有几次有分出两个子数组,渐进时间上还是趋近于 O(nlogn) 的,所以平均效率上是极好的

  • 空间复杂度:1

在 partition 阶段进行两两交换,没有使用其他额外的空间,复杂度为 O(1)

  • 原址排序

在原数组内交换元素,使用区间作为排序界线

  • 不稳定的

由于交换是小于等于 pivot 的一律向前交换,所以当 pivot 选取到存在重复的元素时会出现相对顺序改变的问题,所以算法是不稳定的

Java 实现

java">public class QuickSort {
    public static void sort(int[] A) {
        sort(A, 0, A.length - 1);
    }

    private static void sort(int[] A, int l, int r) {
        if (l < r) {
            int m = partition(A, l, r);
            sort(A, l, m - 1);
            sort(A, m + 1, r);
        }
    }

    private static int partition(int[] A, int l, int r) {
        int pivot = A[r];
        int i = l - 1;
        for (int j = l; j < r; j++) {
            if(A[j] <= pivot) {
                int tmp = A[++i];
                A[i] = A[j];
                A[j] = tmp;
            }
        }
        A[r] = A[i + 1];
        A[i + 1] = pivot;
        return i + 1;
    }
}

java">public class QuickSortTest {
    @Test
    public void test() {
        int[] A = new int[]{1,3,5,7,9,2,4,6,8,0};
        int[] ans = new int[]{0,1,2,3,4,5,6,7,8,9};
        System.out.println("origin: " + Arrays.toString(A));
        QuickSort.sort(A);
        System.out.println("sorted: " + Arrays.toString(A));
        assertArrayEquals(ans, A);
    }
}
  • 输出
origin: [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
sorted: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

结语

作为拥有最好的比较排序代价,同时使用最少的额外空间(O(1))的比较算法>排序算法快速排序是最常被调用的算法>排序算法之一。然而在基本款的快排之上,我们还可以在 pivot 的选取上进行优化,使得 partition 过后的子数组更加平均以提升快速排序的平均效率。


http://www.niftyadmin.cn/n/735529.html

相关文章

软件架构师如何工作-架构漫谈阅读笔记

在王概凯先生的9篇关于软件架构师的博客-《架构漫谈》中&#xff0c;我们可以看到文中谈到了架构的定义、含义&#xff0c;架构主要是要认识概念&#xff0c;如何做好架构之架构的切分&#xff0c;然后谈到了软件与架构之间的关系&#xff08;什么是软件&#xff0c;软件架构是…

Review (Homography+Camera calibration) and others(Week 7 + Week 8)

近期的一些学习&#xff0c;发现了一些很好的Blog:   1.Homography 知多少&#xff1f;   2.计算机视觉-相机内参数和外参数   3.计算机视觉中的多视图几何_基于深度学习的视觉三维重建研究总结   4.视差图Disparity与深度图Depth Map的一点知识   5.图形图像渲染原理…

ADT: Stack 栈

ADT: Stack 栈 文章目录ADT: Stack 栈简介参考正文栈结构抽象接口实现要素Java 实现C 实现结语简介 本篇开始介绍 ADT(Abstract Data Type 抽象数据结构)&#xff0c;在计算机科学中除了基本类型如 int、long、char 等&#xff0c;大多数的程序还需要用到其他集成更多细节的抽…

PKAV 发现 Struts2 最新远程命令执行漏洞(S2-037)

香草 2016/06/16 13:280x00 前言刚过完儿童节回来发现struts2 出了S033&#xff0c;于是放下手中的棒棒糖赶紧分析一下。0x01 S2-033 漏洞回顾先来回顾一下S033根据官方描述很明显有两个关键点&#xff1a;第一个是REST Plugin,另一个是Dynamic Method Invocation is enabled.…

ADT: Queue 队列

ADT: Queue 队列 文章目录ADT: Queue 队列简介参考正文队列结构抽象接口实现要素Java 实现(使用范型)C 实现(使用模版类)结语简介 上一篇ADT: Stack 栈介绍了Stack(栈)的数据结构&#xff0c;这一篇来介绍与栈相似的Queue(队列)的数据结构&#xff0c;与栈相同的是都能够向其添…

单视图测量 (2D变换、影消点线、单视图重构)

写在前面&#xff1a;本篇Blog仅作为学习笔记&#xff0c;学习内容来自于北邮CV-XUEBA团队的三维重建(精简版&#xff0c;鲁鹏)课程。 回顾经典2D变换 等距变换 旋转矩阵(Rotate Matrix)的性质分析 证明&#xff1a;旋转矩阵是正交矩阵 相似变换 仿射变换 因为6个自由度&am…

Sorting 排序算法: Heap Sort 堆排序

Sorting 排序算法: Heap Sort 堆排序 文章目錄Sorting 排序算法: Heap Sort 堆排序簡介參考正文算法思想原理输入算法思想算法流程算法复杂度分析Java 实现結語簡介 今天来介绍一个相对于其他比较排序算法比较特别的一个排序算法-堆排序(HeapSort)&#xff0c;堆排序顾名思义借…

三维重建基础与极几何

蓝色 紫色 红色 写在前面&#xff1a;本篇Blog仅作为学习笔记&#xff0c;学习内容来自于北邮CV-XUEBA团队的三维重建(精简版&#xff0c;鲁鹏)课程。 三维重建基础 三维重建总结 主要涉及以下几个关键问题&#xff1a; 解决第三个关键问题(对应关系)的方法 极几何 极几何…