c++ 快速排序_常用排序算法之快速排序

前天给大家分享了归并排序,但是它不是原地排序算法,需要消耗额外的内存空间,今天给大家分享的是江湖无人不知无人不晓的"快排"--快速排序。

快排是小生接触开发学会的第一个排序算法

快速排序原理

快排也用到了分治思想。快排的核心思想是:如果要排序的数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为分区点 pivot。

我们遍历p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。经过这一步之后,数组 p 到 r 之间的数据就被分成了三个部分,前面 p 到 q-1 之间都是小于 pivot 的,中间是 pivot ,后面的 q+1 到 r 之间都是大于 pivot 的。

如下图:

5e3638c8398589d88087c12a8fde3944.png

根据分治、递归的处理思想,我们可以用递归排序从下标 p 到 q-1 之间的数据和下标从 q+1 到 r 之间的数据,直到区间缩小为1,就说明所有的数据都有序了。快排不需要归并那样做合并,也不需要额外的存储空间,在时间复杂度一样的情况下有着比归并更好的空间复杂度表现。

快排首先找到分区点,一般我们会将数组第一个或最后一个元素作为 pivot,我们以最后一个作为分区点 pivot,然后通过两个变量 i 和 j 作为下标来循环数组,当下标 j 对应数据小于 pivot 时,交换 i 和 j 对应数据,并且将 i往前移动一位,否则 i 不动,下标 j 始终是往前移动的, j 到达终点后,将 pivot 如下标 i 对应数据交换,这样最终将 pivot 置于数组中间,[0...i-1]区间的数据都比 pivot 小,[i+1...j] 之间的数据都比 pivot 大,我们以递归的方式循环处理,最终整个数组都会变成有序的,如下图:

0a41602fa71aa11c67834b7eb668f42d.png

因为分区的过程涉及交换操作,如果数组中有两个相同的元素,比如序列 7, 9,5,7,3,6 经过第一次分区操作之后,两个 7的相对先后顺序会改变。所以,快速排序并不是一个稳定的排序算法。

代码示例

Go语言:

package mainimport "fmt"func main() {  arr := []int{8, 3, 4, 5, 9, 2, 1}  QuickSort(arr)  fmt.Println(arr)}func QuickSort(arr []int) {  separateSort(arr, 0, len(arr)-1)}func separateSort(arr []int, start, end int) {  if start > end {    return  }  i := partition(arr, start, end)  separateSort(arr, start, i-1)  separateSort(arr, i+1, end)}func partition(arr []int, start, end int) int {  pivot := arr[end]  var i = start  for j := start; j < end; j++ {    if arr[j] < pivot {      if !(i == j) {        arr[i], arr[j] = arr[j], arr[i]      }      i++    }  }  arr[i], arr[end] = arr[end], arr[i]  return i}

PHP示例:

function quick_sort($nums){    if (count($nums) <= 1) {        return $nums;    }    quick_sort_c($nums, 0, count($nums) - 1);    return $nums;}function quick_sort_c(&$nums, $p, $r){    if ($p >= $r) {        return;    }    $q = partition($nums, $p, $r);    quick_sort_c($nums, $p, $q - 1);    quick_sort_c($nums, $q + 1, $r);}// 寻找pivotfunction partition(&$nums, $p, $r){      $pivot = $nums[$r];    $i = $p;    for ($j = $p; $j < $r; $j++) {        // 原理:将比$pivot小的数丢到[$p...$i-1]中,剩下的[$i..$j]区间都是比$pivot大的        if ($nums[$j] < $pivot) {            $temp = $nums[$i];            $nums[$i] = $nums[$j];            $nums[$j] = $temp;            $i++;        }    }    // 最后将 $pivot 放到中间,并返回 $i    $temp = $nums[$i];    $nums[$i] = $pivot;    $nums[$r] = $temp;    return $i;  }  $nums = [4, 5, 6, 3, 2, 1];  $nums = quick_sort($nums);  print_r($nums);

JS示例:

const swap = (arr, i, j) => {    const temp = arr[i]    arr[i] = arr[j]    arr[j] = temp}// 获取 pivot 交换完后的indexconst partition = (arr, pivot, left, right) => {    const pivotVal = arr[pivot]    let startIndex = left    for (let i = left; i < right; i++) {        if (arr[i] < pivotVal) {            swap(arr, i, startIndex)            startIndex++        }    }    swap(arr, startIndex, pivot)    return startIndex}const quickSort = (arr, left, right) => {    if (left < right) {        let pivot = right        let partitionIndex = partition(arr, pivot, left, right)        quickSort(arr, left, partitionIndex - 1 < left ? left : partitionIndex - 1)        quickSort(arr, partitionIndex + 1 > right ? right : partitionIndex + 1, right)    }}

性能分析

最后我们看下快速排序的性能和稳定性:

  1. 时间复杂度:是O(nlogn),同样要优于冒泡和插入排序
  2. 空间复杂度:不需要额外的空间存放排序的数据,是原地排序
  3. 算法稳定性:涉及数据交换,可能破坏原来相等元素的位置排序,所以是不稳定的排序算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

西门子安装未找到ssf文件_V5.3安装时显示NO SSF FILE FOUND对话框,我该怎么解决啊? 谢谢!-工业支持中心-西门子中国...

我安装过多次step7 v5.3,中文英文版都安装过。从没有遇到这样的问题。是不是你的安装光盘有问题&#xff1f;换一张光盘试验一下&#xff01;回答者&#xff1a; profinet - 中级工程师&nbsp&nbsp第10级2006-10-20 01:18:19这个问题比较简单&#xff0c;建议你在驱动器…

k8s ubuntu cni_手把手教你使用RKE快速部署K8S集群并部署Rancher HA

作者&#xff1a;杨紫熹原文链接&#xff1a;https://fs.tn/post/PmaL-uIiQ/RKE全称为Rancher Kubernetes Engine&#xff0c;是一款经过CNCF认证的开源Kubernetes发行版&#xff0c;可以在Docker容器内部运行。它解决了Kubernetes社区中最常见的问题——安装十分复杂。借助RKE…

linux du -sh 脚本,Linux之shell脚本(2)

Linux之shell脚本(2)一、printf命令&#xff1a;printf是一个把从标准输入的字符按照你所要求的格式输出到标准输出即屏幕的命令.在很多时候&#xff0c;我们可能需要将自己的数据给他格式化输出的。1.格式化输出。(print format)2.命令格式&#xff1a;printf打印格式实际内容…

import oracle utility_教你如何Oracle数据导入

学习Oracle时&#xff0c;你可能会遇到Oracle数据导入问题&#xff0c;这里将介绍Oracle数据导入问题的解决方法&#xff0c;在这里拿出来和大家分享一下。Oracle数据导入实用程序(Import utility)允许从数据库提取数据&#xff0c;并且将数据写入操作系统文件。imp使用的基本格…

linux 管道非阻塞,linux – 管道上的非阻塞读取

可以在管道上进行非阻塞I / O吗&#xff1f; fcntl无法设置O_NONBLOCK. Linux编程接口的页面918包括一个表’从管道读取n个字节或FIFO(p)’的语义.此表列出了管道和FIFO的行为,其中一列标题为O_NONBLOCK已启用&#xff1f;这意味着您可以在管道上设置O_NONBLOCK标志.它是否正确…

python异常值删除_python数据清洗中,是如何识别和处理异常值的?

异常值处理是pythonshujuqingxi/ stylecolor:#000;font-size:14px;>python数据清洗中重要的步骤&#xff0c;虽然异常值出现频率比较低&#xff0c;但是如果置之不理的话&#xff0c;还是会对实际项目的分析造成偏差&#xff0c;所以今天小编就跟大家分享pythonshujuqingxi/…

react 子传参父_react子父传参有几种方法?

react子父传参有几种方法&#xff1f;下面本篇文章给大家介绍一下react父子组件传参(值)的方法。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对大家有所帮助。react父子组件传参(值)的几种方法一、父组件传给子组件父组件通过props传递给子组件&…

啊哈c语言答案1.3,啊哈C语言编程-第2课-让计算机开口说话

为什么会有计算机的出现呢&#xff1f;我们伟大的人类&#xff0c;发明的每一样东西都是为了帮助我们改善生活。计算机同样是用来帮助我们的工具。想一想&#xff0c;假如你现在希望让计算机帮助你做一件事情&#xff0c;你首先需要做什么&#xff1f;是不是要先与计算机进行沟…

python c java_简单明了看懂JAVA,Python和C+的优劣势

Java由于其优越的跨平台可移植性&#xff0c;在Web开发中是主流语言。在加上手机Android系统的发展&#xff0c;使得java开发人员的需求量很大。同时&#xff0c;Java现在也用来开发手游。Java 的语法相对规范。 Python是动态形的灵活的解释性语言&#xff0c;从软件开发到Web开…

c语言源程序文件.c如何保存,急求如何将下列C语言程序数据存储到文件中?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼求如何改动才能将下列程序的存储输入或输出数据(或两者一起)到指定的文件(或运行时直接创立一个文件)如Arrangement中。#include int n0;int rest[7][7]; //全局声明,以供全局调用int main(){void perm(int list[],int ,int );int …

ultraos win10启动盘_UltraISO制作U盘启动安装MSDN原版Win10系统教程 - SDN系统库

UltraISO制作U盘启动安装Win10系统本教程是介绍使用UltraISO(软碟通)制作U盘启动来安装Win10系统&#xff0c;适用于当原系统损坏、崩溃、升级异常导致系统不能开机时重装&#xff0c;相对比《制作U盘PE启动盘方法》更快&#xff0c;且不需要借助任何第三PE/还原工具&#xff0…

python3.6字典有序_为什么Python 3.6以后字典有序并且效率更高?

在Python 3.5&#xff08;含&#xff09;以前&#xff0c;字典是不能保证顺序的&#xff0c;键值对A先插入字典&#xff0c;键值对B后插入字典&#xff0c;但是当你打印字典的Keys列表时&#xff0c;你会发现B可能在A的前面。 但是从Python 3.6开始&#xff0c;字典是变成有顺序…

linux 依赖关系解析失败,关于linux依赖关系出错的解决

我在装caffe时遇到的错误如下&#xff1a;apt-get: 代码:sudo apt-get install libgl1-mesa-dev正在读取软件包列表... 完成正在分析软件包的依赖关系树正在读取状态信息... 完成有一些软件包无法被安装。如果您用的是 unstable 发行版&#xff0c;这也许是因为系统无法达到您要…

以前是传xml的吗_明明不太合适但是还是被用在配置文件和数据传输上的XML

XML概述&#xff1a;概念&#xff1a;可扩展的标记语言。功能&#xff1a;作为数据本地存储的格式。(已淘汰)作为结构化存储的方式&#xff0c;不如数据库效率高。目前一部分移动设备中还在使用。作为网络中传输数据的格式。(已淘汰)作为网络传输的格式&#xff0c;在目前以移动…

用html5做一个简单网页_用新款ws2812灯带做一个简单的窗花

本文转自&#xff1a;DF创客社区-未经许可不可转载原文链接&#xff08;附件请于原文下方下载&#xff09;&#xff1a;用新款ws2812灯带做一个简单的窗花-创意生活论坛-DF创客社区​mc.dfrobot.com.cn作者&#xff1a;屌丝王小明很高兴提前拿到了DF即将上架的新品——ws2812灯…

c语言锁屏密码程序,求一个VB锁屏程序的源文件

满意答案nan67182014.07.08采纳率&#xff1a;53% 等级&#xff1a;12已帮助&#xff1a;8369人我原来写的一个缩屏的程序&#xff0c;后来没用&#xff0c;当时只是为了测试透明窗体的.代码给你参考下。功能差一个禁用任务管理器的功能Private Declare Function GetWindowL…

抗侧力构件弹性位移如何计算_说一说现在很火的装配式建筑怎么计算?

装配整体式剪力墙结构体系&#xff0c;其主要预制构件包括承重墙(预制剪力墙)、非承重墙(外填充墙、内隔墙等)、预制楼梯(预制楼梯梯段&#xff0c;端部伸出连接钢筋&#xff0c;伸入叠合平台板&#xff0c;通过叠合现浇形成整体楼梯)、预制阳台板(根据建筑要求&#xff0c;整体…

微软私有云解决方案_微软发布电信云平台 ,互联网巨头争夺5G网络商机

微软发布电信云平台 &#xff0c;互联网巨头争夺5G网络商机微软公司周一发布了全新的云平台&#xff0c;能够帮助电信运营商更快地构建5G网络&#xff0c;降低成本并向企业客户出售定制服务。这一5G的新平台将在微软云Azure上运行&#xff0c;微软表示使用该平台将降低基础架构…

用c语言编程参赛信息查询,确定参赛者名单(C语言实现)

/*2011第二届国信蓝点杯全国软件专业人才设计与开发大赛2011第二届国信蓝点杯全国软件专业人才设计与开发大赛选拔赛试题-Java语言高职组最后一题题&#xff1a;A、B、C、D、E、F、G、H、I、J 共10名学生有可能参加本次计算机竞赛&#xff0c;也可能不参加。因为某种原因&#…

bind merge r 和join_R语言并行读取csv:地表最快csv合并方法

作者&#xff1a;黄天元&#xff0c;复旦大学博士在读&#xff0c;热爱数据科学与开源工具&#xff08;R&#xff09;&#xff0c;致力于利用数据科学迅速积累行业经验优势和科学知识发现&#xff0c;涉猎内容包括但不限于信息计量、机器学习、数据可视化、应用统计建模、知识图…