当前位置: 首页 > news >正文

周周爱学习之快速排序

        快速排序,顾名思义,快速排序是一种速度非常快的一种排序算法

  • 平均时间复杂度为O(nlog_{2}n),最坏时间复杂度为O(n^{^{2}})
  • 数据量较大时,优势非常明显
  • 属于不稳定排序

1.算法描述

  1. 每一轮排序选择一个基准点(pivot)进行分区

    1. 让小于基准点的元素的进入一个分区,大于基准点的元素的进入另一个分区

    2. 当分区完成时,基准点元素的位置就是其最终位置

  2. 在子分区内重复以上过程,直至子分区元素个数少于等于 1,这体现的是分而治之的思想 (divide-and-conquer)

  3. 从以上描述可以看出,一个关键在于分区算法,常见的有洛穆托分区方案、双边循环分区方案、霍尔分区方案

2.单边循环快排(lomuto 洛穆托分区方案)

  1. 选择最右元素作为基准点元素

  2. j 指针负责找到比基准点小的元素,一旦找到则与 i 进行交换

  3. i 指针维护小于基准点元素的边界,也是每次交换的目标索引

  4. 最后基准点与 i 交换,i 即为分区位置

代码实现

    public static void main(String[] args) {int[] a = {5, 3, 7, 2, 9, 8, 1, 4};System.out.println(Arrays.toString(a));quick(a, 0, a.length - 1);}public static void quick(int[] a, int l, int h) {if (l >= h) {return;}int p = partition(a, l, h); // p 索引值quick(a, l, p - 1); // 左边分区的范围确定quick(a, p + 1, h); // 左边分区的范围确定}private static int partition(int[] a, int l, int h) {int pv = a[h]; // 基准点元素int i = l;for (int j = l; j < h; j++) {if (a[j] < pv) {if (i != j) {swap(a, i, j);}i++;}}if (i != h) {swap(a, h, i);}System.out.println(Arrays.toString(a) + " i=" + i);// 返回值代表了基准点元素所在的正确索引,用它确定下一轮分区的边界return i;}

3.双边循环快排(不完全等价于 hoare 霍尔分区方案)

  1. 选择最左元素作为基准点元素

  2. j 指针负责从右向左找比基准点小的元素,i 指针负责从左向右找比基准点大的元素,一旦找到二者交换,直至 i,j 相交

  3. 最后基准点与 i(此时 i 与 j 相等)交换,i 即为分区位置

要点

  1. 基准点在左边,并且要先 j 后 i

  2. while( i < j && a[j] > pv ) j--

  3. while ( i < j && a[i] <= pv ) i++

代码实现

    public static void main(String[] args) {int[] a = {5, 3, 7, 2, 9, 8, 1, 4};System.out.println(Arrays.toString(a));quick(a, 0, a.length - 1);}private static void quick(int[] a, int l, int h) {if (l >= h) {return;}int p = partition(a, l, h);quick(a, l, p - 1);quick(a, p + 1, h);}private static int partition(int[] a, int l, int h) {int pv = a[l];int i = l;int j = h;while (i < j) {// j 从右找小的while (i < j && a[j] > pv) {j--;}// i 从左找大的while (i < j && a[i] <= pv) {i++;}swap(a, i, j);}swap(a, l, j);System.out.println(Arrays.toString(a) + " j=" + j);return j;}

http://www.lryc.cn/news/253212.html

相关文章:

  • 国产接口测试工具APIpost
  • MySQL电商管理系统练习题及答案
  • 每日3道PWN(第二天)
  • SAP STMS传输请求
  • L1-009:N个数求和
  • 当发送“Hello,World”时,channel发生了什么?
  • 服务器运行情况及线上排查问题常用命令
  • Hadoop学习笔记(HDP)-Part.18 安装Flink
  • LeetCode56. 合并区间
  • 解决typescript报错:找不到名称xxx
  • UVM中封装成agent
  • OSI七层模型与TCP/IP四层模型
  • QT 中 QProgressDialog 进度条窗口 备查
  • 学习ShardingSphere前置知识
  • 读书笔记-《数据结构与算法》-摘要3[选择排序]
  • Arduino驱动MLX90614红外测温传感器(温湿度传感器)
  • Ubuntu上传文件到SMB共享文件夹
  • 【Linux】基础IO--重定向理解Linux下一切皆文件缓冲区
  • RINEX介绍
  • ROS-ROS通信机制-服务通信
  • chown和chmod
  • 【GPU】linux 安装、卸载 nvidia 显卡驱动、cuda 的官方文档、推荐方式(runfile)
  • 6页手写笔记总结信号与系统常考知识大题知识点
  • Qt-QSplitter正确设置比例
  • 一篇吃透大厂面试题,2024找工作一帆风顺。
  • 【1day】用友 U8 Cloud系统TaskTreeQuery接口SQL注入漏洞学习
  • 华为快应用中自定义Slider效果
  • C语言每日一题(43)旋转链表
  • CCF计算机软件能力认证考试—202209-1如此编码
  • Ubuntu18.04安装Ipopt-3.12.8流程