快速排序(一)

2023-11-03

 

快速排序是冒泡排序,选择排序,插入排序,奇偶排序,,归并排序,希尔排序中最快的排序,所以我们当然有必要去深入了解快速排序。

我们首先来了解一下划分算法,

何谓划分算法?

其实就是以一个数为基准(枢纽),这个比枢纽大的数,把我们它在数组的右边,这个比枢纽小的我们放左边

那我们如何来做呢?

假设现在我们有一个数组,上面杂乱无章的有十个数字,我们以50为枢纽,比50大的放在数组右边,比50小的放在数组左边。

起初:

1开始:

谨记规则:比枢纽小的放左边,比枢纽大的放右边

我们用LEFTARROW从数组左侧开始寻找,找到比枢纽数大的数字我们就停下,如果没找到,就一直往下遍历

相应的,我们用向右键从数组右侧开始寻找,找到比枢纽数小的我们就停下,如果没找到,就一直往下遍历

2-若停下:

交换数据

3-继续往下找:

4-若停下

交换数据

......(重复上述过程,直到左边的数都比枢纽的要小,右边的的数都比枢纽要大)

最后的结果如图:

在这里我们可以发现结束的条件应为LEFTARROW>向右键

那么LEFTARROW =向右键要不要结束条件,我们想一想它们什么时候会都指向同一个数字,是不是那个数字就是基准数的时候,两个箭头指向同一个数,说明左边的数全都已经比枢纽小,右边的全都比枢纽要大。

所以结束条件为:LEFTARROW> =向右键

知道上述过程,理解代码就容易多了:

int leftArrow = -1;

int rightArrow = 10; (也就是数组的容量)

而(theArray [++ LEFTARROW] <枢轴); 

而(theArray [ - 向右键>枢轴]);

交换(theArray [LEFTARROW],theArray [向右键]);

注:交换为执行交换两个数的方法(函数),枢轴为枢纽的意思

我们执行完一遍以后要继续遍历,所以很可以自然的想到要循环上述过程,也就是重复上述过程

所以我们加个而循环:

而(真){

          而(theArray [++ LEFTARROW] <枢轴); 

          而(theArray [ - 向右键>枢轴]);

          交换(theArray [LEFTARROW],theArray [向右键]);

}

前面已经讲过,如果LEFTARROW> =向右键,我们的目的就达到了,左边放的都是比枢纽下的数,右边放的都是比枢纽大的数,停止循环。

而(真){

          而(theArray [++ LEFTARROW] <枢轴); 

          而(theArray [ - 向右键>枢轴]);

           如果(LEFTARROW> =向右键)

                     打破;

          交换(theArray [LEFTARROW],theArray [向右键]);

}

考虑特殊情况;

上面都是杂乱无章的数,有比枢纽大的数,有比枢纽小的数,那么如果全都的英文比枢纽小的数,我们按照上面的代码运行的话会出现什么样的状况呢答案就是:造成数组越界相同的,如果,全都是比枢纽大的数,也会造成数组越界为了防止这种情况,我们需要在找比枢纽大或找比枢纽小的,而循环里面要增添条件:因为我们起初都是先自增以后再跟枢纽比较,举个例子,我们假设数组容量为10,当我们的LEFTARROW已经指向8时,我们判断其<9,所以我们自增LEFTARROW指向图9中,将theArrow [9]和枢纽枢轴进行比较,此时已经到达数组最后一个元素了,下次判断的时候,LEFTARROW <9,但此时LEFTARROW指向的是图9中,我们就不再继续遍历下去了,假设我们再继续遍历下去,LEFTARROW先自增以后,就是theArray [10]和枢纽枢轴比较,这样就会造成数组下标越界。

而(真){

          while(leftArrow <9 && theArray [++ leftArrow] <pivot); 

          while(rightArrow> 0 theArray [ - rightArrow> pivot]);

           如果(LEFTARROW> =向右键)

                     打破;

          交换(theArray [LEFTARROW],theArray [向右键]);

}

经过上述操作,我们就完成我们想要达到的目的:比枢纽小的放在左边,比枢纽大的统一放在右边。

这就是快速排序最基本的思想,如果我们又把分好的两组又像上述过程那样,又设定一个枢纽值,又按照上述规则划分,大的放一边,小的放一边,完成有,我们又这样,又设定一个枢纽,然后划分,这样一直重复上述过程(很容易想到递归方法)是不是就可以完成排序了呢?没错,这就是快速排序。

那么我们如何实现快速排序呢?按照上面的思路,我们最重要的就是要知道枢纽,因为数组里面的数都是按枢纽来排序的,打的放右边,小的放左边,为了排序这一列的数组,我们当然不能像上面那样无中生有的直接创造一个枢纽,所以我们的枢纽设置为是数组里面的一个数,为了简单,暂且我们将枢纽:均设置为最右边的数。

排序都是一整列的,为了方便用户我们定义一个方法,方法里面再调用快速排序。

public void QuickSort(){

           reQuickSort(0,nElems-1);

}

public void reQuickSort(int left,int right){

              如果(左> =右)

                  返回;

              int pivot = theArray [right];

              int partition = partition(left,right,pivot);

              reQuickSort(左,分区-1);

              reQuickSort(分区+ 1,右边);

} // partiton是分区的意思,我们通过partition获取中止的地方小标,将数组“拆分”成两半,分别进行划分(大放一边小放一边)

public int partition(int left,int right,int pivot){

            int leftArrow = left - 1;

            int rightArrow = right;

  而(真){         

           而(theArray [++ LEFTARROW] <枢轴); //不需要另加条件的原因是,我们是以最右边的数为枢纽的,不会出现数全小于枢纽的//的情况,遍历到最后一个总是是等于枢纽的,所以不用考虑数组越界的问题

           while(rightArrow> 0 && theArray [ - right]> pivot); //按照上面想法,下标有可能越界

           如果(LEFTARROW> =向右键)

                       打破;

           交换(LEFTARROW,向右键);             

       }

       交换(LEFTARROW,右);

       return leftArrow;

}

转下篇:https://blog.csdn.net/szlg510027010/article/details/83108239

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

快速排序(一) 的相关文章

  • 快速排序(一)

    快速排序是冒泡排序 选择排序 插入排序 奇偶排序 归并排序 希尔排序中最快的排序 所以我们当然有必要去深入了解快速排序 我们首先来了解一下划分算法 何谓划分算法 其实就是以一个数为基准 枢纽 这个比枢纽大的数 把我们它放在数组的右边 这个比
  • 以第一个元素作为主元的快速排序示例

    我目前正在研究快速排序 想知道当第一个 或最后一个 元素被选为枢轴点时它是如何工作的 比如说我有以下数组 15 19 34 41 27 13 9 11 44 这就是我认为发生的情况 15 19 34 41 27 13 9 11 44 piv
  • C随机主元快速排序(改进配分函数)

    我是一名计算机科学专业的学生 刚刚开始 我正在努力从伪代码编写快速排序的随机枢轴版本 我已经编写并测试了它 但一切都很完美 分区部分看起来有点太复杂了 感觉漏掉了什么或者想太多了 我不明白这是否可以 或者我是否犯了一些可以避免的错误 长话短
  • 快速排序未正确排序

    试图从快速排序的实现中学习 我无法找出它排序不正确的原因 使用这个序列 6 7 12 5 9 8 65 3 它返回这个 3 5 7 8 9 65 12 6 似乎有点排序 但不是全部 我错过了什么 这是我的代码 static void Mai
  • stable_partition 如何成为自适应算法?

    stable partition是c STL算法头文件中的函数模板 我读到它是一种自适应算法 其时间复杂度为 O n logn 或 O n 具体取决于某些因素 有人可以解释一下这些因素是什么以及时间复杂度如何取决于这些因素 谢谢 有2 实施
  • 改进快速排序

    如果可能 我如何改进以下快速排序 性能方面 有什么建议么 void main quick a 0 n 1 void quick int a int lower int upper int loc if lower
  • 快速排序与堆排序

    快速排序和堆排序都进行就地排序 哪个更好 首选哪种应用和案例 堆排序是 O N log N 保证的 这比快速排序中最坏的情况要好得多 堆排序不需要更多内存来让另一个数组像合并排序那样放置有序数据 那么为什么商业应用程序坚持使用快速排序呢 与
  • 为什么要费心比较排序呢?

    Timsort Quicksort 和 Mergesort 等算法在 真实世界 排序方法 这些比较排序的案例非常实用 它们已被证明是在各种环境中性能最高 最稳定 多用途的排序算法 然而 似乎我们在计算机上排序的几乎所有内容都是可数 部分排序
  • Java:赛车数组.sort

    我对 QuickSort 进行了一些改进 并决定针对 Java 进行测试Arrays sort 结果很有趣 在 Java 6 上 我的时间 系统时间 74 83 0 891566265060241 我的时间 系统时间 75 79 0 949
  • 等待执行器中的所有线程完成?

    我正在实现并行快速排序作为编程实践 完成后 我阅读了 Executors 上的 Java 教程页面 这听起来像是它们可以使我的代码更快 不幸的是 我依靠 join 来确保程序在所有内容都排序完成之前不会继续 现在我正在使用 public s
  • 以中间元素为基准的快速排序

    我对快速排序的理解是 选择一个枢轴元素 在本例中我选择中间元素作为 枢 在极值处初始化左指针和右指针 找到枢轴左侧第一个大于枢轴的元素 同样找到枢轴右侧第一个小于枢轴的元素 交换 3 和 4 中的元素 重复 3 4 5 除非左 gt 右 对
  • 使用quickSort时出现stackoverflowerror,我可以增加堆栈和堆吗?

    java中可以增加栈和堆吗 我用的是BlueJ EDIT 这是代码 Quick Sort Method public static void quickSort int data int first int n int p n1 n2 if
  • 快速排序递归深度 O(n) 的堆栈空间不会导致堆栈溢出?

    在最坏的情况下 快速排序递归深度需要 O n 的堆栈空间 为什么在最坏的情况下它不会导致大集合的堆栈溢出 顺序颠倒 如果在枢轴的两侧进行递归 那么在最坏的情况下 它确实会导致足够大的数据的堆栈溢出 这就是为什么没有人在生产代码中使用简单的快
  • 快速排序 - 哪个子部分应该首先排序?

    我正在阅读一些文本 其中声称有关两个递归快速排序调用的顺序 首先调用较小的子问题很重要 这与尾递归结合使用可确保堆栈深度为 log n 我完全不确定这意味着什么 为什么我应该首先对较小的子数组调用快速排序 将快速排序视为隐式二叉树 枢轴是根
  • 多线程排序算法

    我必须在 Java 中为我的算法类实现多线程合并排序和快速排序 并将它们与我的单线程版本进行比较 不过 我以前从未使用过多线程 我的代码可以是多线程的还是必须重新开始 这是我的单线程算法代码 归并排序 sort 方法是我必须实现的策略模式的
  • 3路快速排序(C实现)

    我试着实施 https github com p1v0t Sort一些算法是使用 C 的纯通用算法 我坚持使用 3 路快速排序 但不知何故 实现没有给出正确的输出 输出几乎已排序 但某些键不在应有的位置 代码如下 提前致谢 include
  • 快速排序和调整快速排序有什么区别?

    快速排序和调整快速排序之间的根本区别是什么 快速排序有何改进 Java 如何决定使用它而不是合并排序 正如蜥蜴比尔所说 调整的快速排序仍然具有与基本快速排序相同的复杂性 O N log N 平均复杂度 但调整的快速排序使用一些不同的方法来尝
  • 查找数组中的 K 个最小值(堆 vs QuickSelect)

    假设我们有一个数组 我们希望找到它的 K 个最小值 有两种方法 1 使用快速选择算法 O n 时间复杂度和O 1 空间 2 使用最小堆数据结构 O NlogK 时间复杂度和O K 空间 我想知道什么时候一个比另一个更受青睐 我想这两个都可以
  • Python 比编译的 Haskell 更快?

    我有一个用 Python 和 Haskell 编写的简单脚本 它读取包含 1 000 000 个换行符分隔的整数的文件 将该文件解析为整数列表 对其进行快速排序 然后将其写入已排序的不同文件中 该文件与未排序的文件具有相同的格式 简单的 这
  • 具有 3 路划分的快速排序

    什么是三向分区快速排序 画一个数组 3 5 2 7 6 4 2 8 8 9 0 A 两分区快速排序会选择一个值 比如 4 并将每个大于 4 的元素放在数组的一侧 将每个小于 4 的元素放在另一侧 就像这样 3 2 0 2 4 8 7 8 9

随机推荐

  • OK彻底解决ping主机ping虚拟机之间ping不通的问题

    时间轴 一个月前 2022 8 重新玩虚拟机 因为计算机网络这块不扎实 知识点模糊 不懂其中各种原由 当然现在也不是很明白 后续还需要系统的回顾 在那是一直有几个问题 遇到以下问题需要解决 1 怎么选择桥接 nat的连接方式 现在也不清楚
  • 第七章 单行函数

    MySQL系列文章目录 http t csdn cn YTPe9 文章目录 MySQL系列文章目录 前言 一 函数的理解 1 什么是函数 2 不同DBMS函数的差异 3 MySQL的内置函数及分类 二 数值函数 1 基本函数 2 角度与弧度
  • C 语言char类型与int类型的转化

    目录 一 char转int 法一 直接转换 ASSCII编码表 ASCII可显示字符 法二 利用库函数转换 二 数字换成字符串 1 用sprintf 2 用库函数 char和int的转换有两种方式 这两种方式适合于在输出时使用 一 char
  • Android studio实现个人体重指数计算

    Java代码 package com example work1 import android app Activity import android app AlertDialog import android content Dialo
  • 基于 Android NDK 的学习之旅----- C调用Java(附源码)

    许多成熟的C引擎要移植到Android 平台上使用 一般都会 提供 一些接口 让Android sdk 和 jdk 实现 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态方法 1 主要流程 1 新建一个测试类TestP
  • linux执行命令缺少共享库解决方法和ldd命令说明

    linux执行命令缺少共享库解决方法和ldd命令说明 root xiaogaokui which ldd usr bin ldd root xiaogaokui file usr bin ldd usr bin ldd Bourne Aga
  • ZStack-K8s三层互联互通方案

    1 准备条件 zstack社区版 kubernetes 1 15 0 zstack 创建私有网络 kubernetes 选择Calico网络方案 kubernetes创建在zstack创建的扁平网络中或者是kubernetes和zstack
  • web H5 调用高德地图 通过ip定位获取当前城市

    web H5 调用高德地图 通过ip定位获取当前城市 一 使用步骤注册高德账号 创建应该获取key 登录之后 点击 应用 头部导航栏 注册地址拿走 https lbs amap com dev id choose 注意这里有服务类型 提交完
  • 拉格朗日法插补数据缺失值(Python代码实现)

    1 查询缺失值位置 isnull for i in df columns for j in df index if df isnull loc j i isnull append j i isnull 2 拉格朗日插值 传入存在缺失值的列
  • PCL 三维点云边界提取(C++详细过程版)

    边界提取 一 概述 二 代码实现 三 结果展示 本文由CSDN点云侠原创 爬虫自重 如果你不是在点云侠的博客中看到该文章 那么此处便是不要脸的爬虫 一 概述 点云边界提取在PCL里有现成的调用函数 具体算法原理和实现代码见 PCL 点云边界
  • r语言插补法_R语言缺失值的处理:线性回归模型插补

    在当我们缺少值时 系统会告诉我用 1代替 然后添加一个指示符 该变量等于 1 这样就可以不删除变量或观测值 我们在这里模拟数据 然后根据模型生成数据 未定义将转换为NA 一般建议是将缺失值替换为 1 然后拟合未定义的模型 默认情况下 R的策
  • Wireshark网络封包分析软件使用心得

    Wireshark网络封包分析软件使用心得 Wireshark 前称Ethereal 是一个网络封包分析软件 网络封包分析软件的功能是截取网络封包 并尽可能显示出最为详细的网络封包资料 Wireshark使用WinPCAP作为接口 直接与网
  • 资源池 'default' 没有足够的系统内存来运行此查询

    今天 有个客户突然打电话跟我说他的系统出了点问题 一个查询查了几十秒才出来 有时候还出不来 于是我上去看了一下 打开数据库看了相关视图 发现查询确实很慢 运行多次之后出现 资源池 default 没有足够的系统内存来运行此查询 嗯 这句话的
  • selenium抓取元素排除某个特定的class标签

    排除某个因素 第一优选想到正则表达式 无奈折腾半天没有成功 感觉是对元素的attrs按search在操作 对字符串末尾检测都没什么用 语法如下 text match By XPATH tr 5 td 11 div r 0 1 1 0 9 6
  • 【问题及解决】ImportError: libpython3.7m.so.1.0: cannot open shared object file: No such file or directory

    报错 是说少了一个libpython3 7m so 1 0的库 解决参考 https github com deepmind acme issues 47 解决办法 export LD LIBRARY PATH path to libpyt
  • 7 个建议让 Code Review 高效又高质

    简介 Code Review CR 的本质是什么 是为了查错 还是为了 KPI 本文分享阿里资深技术专家的看法 CR 是一种关于社会学的长期行为和组织文化 通过 CR 形成一种良性互动的技术氛围 传播和分享知识 提升代码质量 并给出了 7
  • 签约减碳计算模型背后:重新定义ESG

    如果将法大大比做电子签界的 支付宝 那么其减碳计算模型更像是 蚂蚁森林 向内输血 向外赋能 作者 斗斗 出品 产业家 纸张 打印 包装 运输 所有环节的碳排放因子被带入公式后 签约场景的碳排放清晰可见 至此 每一份合同的碳排放都有了清晰的度
  • L2-005 集合相似度 (25 分)

    题目 题目链接 题解 STL 一开始我用的map 由于使用其size函数 一直出错 我发现map的size函数很不稳定 我是定义的
  • 并行程序设计作业7/12

    这里用的是信号量 有需求可以改成其他的 首先要新开一个桶存起来 然后得到资源在写进结果数组 如果不这样多核会比单核还慢 因为写操作并没有优化 然后我这里用了map 如果桶编号大 每个核心结果离散度比较大时 用数组会慢很多 map在离散度大的
  • 快速排序(一)

    快速排序是冒泡排序 选择排序 插入排序 奇偶排序 归并排序 希尔排序中最快的排序 所以我们当然有必要去深入了解快速排序 我们首先来了解一下划分算法 何谓划分算法 其实就是以一个数为基准 枢纽 这个比枢纽大的数 把我们它放在数组的右边 这个比