快速排序(一)

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(使用前将#替换为@)

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

  • C OpenMP 并行快速排序

    在 C 中使用 openMP 时 我再次陷入困境 这次我尝试实现并行快速排序 Code include
  • Java 中的就地快速排序

    为了刷新一些 Java 我尝试实现一个可以对整数数组进行排序的快速排序 就地 算法 以下是我到目前为止得到的代码 你可以通过以下方式调用它sort a 0 a length 1 如果两个 指针 都存在 则此代码显然会失败 进入无限循环 i
  • 另一个快速排序 stackoverflow

    所以我一直在尝试自己实现一个快速排序 只是为了从中学习一些东西 但它也生成了一个stackoverflowException 但我似乎找不到原因是什么 有人可以给我线索吗 public void Partition List
  • QuickSort 程序达到最大递归限制 500?

    我正在通过在 MATLAB 中绘制图形来分析排序算法 下面是我的快速排序代码 当我运行它时 它给出了这个错误 最大递归限制500到达 使用set 0 RecursionLimit N 更改限制 请注意 超出您的可用堆栈空间 可能会使 MAT
  • 快速排序未正确排序

    试图从快速排序的实现中学习 我无法找出它排序不正确的原因 使用这个序列 6 7 12 5 9 8 65 3 它返回这个 3 5 7 8 9 65 12 6 似乎有点排序 但不是全部 我错过了什么 这是我的代码 static void Mai
  • 为什么 Android/Java API 中的对象要使用合并排序?

    In Java 数组 sort 对于原始类型使用快速排序 另一方面数组 sort 对于对象使用归并排序 并且 同样适用于集合 sort 它也使用归并排序 集合排序使用底层的数组排序实现 因此 从简单的意义上来说 我可以说基元是使用快速排序来
  • stable_partition 如何成为自适应算法?

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

    我很想知道我的非递归快速排序算法的实现是否存在一些缺点或隐藏的问题 为了优化它应该修改什么 以我的方式比较两个对象时可能会发生什么问题 public class QuickSort
  • 为什么要费心比较排序呢?

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

    我观看了快速排序算法的精彩可视化 http www youtube com watch v Z5nSXTnD1I4 http www youtube com watch v Z5nSXTnD1I4 我觉得我真的理解了快速排序背后的原理 并且
  • 快速排序递归深度 O(n) 的堆栈空间不会导致堆栈溢出?

    在最坏的情况下 快速排序递归深度需要 O n 的堆栈空间 为什么在最坏的情况下它不会导致大集合的堆栈溢出 顺序颠倒 如果在枢轴的两侧进行递归 那么在最坏的情况下 它确实会导致足够大的数据的堆栈溢出 这就是为什么没有人在生产代码中使用简单的快
  • 是否可以只通过一次就对列表进行快速排序?

    我正在学习haskell 我看到的函数定义是 quickSort x xs quickSort less x equal quickSort more where less filter lt x xs equal filter x xs
  • 伪快速排序时间复杂度

    我知道快速排序有O n log n 平均时间复杂度 经常用于演示函数式语言的简洁性的伪快速排序 仅当您从足够远的地方看时 具有适当高的抽象级别时 它才是快速排序 如下 在 Haskell 中给出 quicksort Ord a gt a g
  • 多线程排序算法

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

    如果排序算法保留具有 equals 键的任意两个元素的相对顺序 则该算法是稳定的 快速排序在什么条件下稳定 当没有项被传递时 快速排序是稳定的 除非它具有较小的键 还有哪些条件可以使其稳定 嗯 使用 O N 空间而不是就地不稳定实现使用的
  • 快速排序时间复杂度最佳情况输入

    我必须找到 C 程序中最佳情况输入的快速排序的时间复杂度 并且我选择了数组的最后一个元素作为枢轴 现在我知道在最佳情况下必须输入什么输入值 即将第一个中间元素保留在最后一个位置 枢轴 下一个枢轴应该是下一个中间元素 但我必须生成这种最好情况
  • 这里使用尾递归有什么好处?

    我一直在阅读描述如何通过使用尾递归版本来降低快速排序的空间复杂度的文章 但我无法理解这是怎么回事 以下是两个版本 QUICKSORT A p r q PARTITION A p r QUICKSORT A p q 1 QUICKSORT A
  • 快速排序特殊情况 - 似乎是 K&R 的错误算法

    我在理解 K R 的快速排序算法 没有指针的简化版本 时遇到问题 Dave Gamble 已经在这里提供了详尽的解释解释 https stackoverflow com questions 1231254 kr qsort example
  • Python 中的快速排序实现

    我正在尝试在 python 中实现快速排序 但是 我的代码没有正确排序 不完全 例如 在输入数组 5 3 4 2 7 6 1 上 我的代码输出 1 2 3 5 4 6 7 所以 最终结果插入了 4 和 5 我承认我对 python 有点生疏
  • 二叉堆对于优先级队列的优点?

    看来我错过了一些非常简单的东西 优先级队列的二进制堆与快速排序的值数组相比有什么优势 在这两种情况下 我们将值保存在数组中 插入的时间复杂度为 O logN 删除最大的时间复杂度为 O 1 在这两种情况下 给定元素数组的初始构造都是 O N

随机推荐

  • 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在离散度大的
  • 快速排序(一)

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