【C/C++ 05】快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序算法,其基本思想是:任取待排序序列中的某元素作为基准值,按照该基准值将待排序集合分割成两个子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后左右子序列递归该过程,直到所有元素都排列在相应的位置上为止。

  • 排序对象:数组、链表
  • 时间复杂度:O(n * \log n)
  • 空间复杂度:O(1)
  • 是否稳定:否
// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int array[], int left, int right)
{if(right - left <= 1)return;// 按照基准值对array数组的 [left, right)区间中的元素进行划分int div = partion(array, left, right);// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)// 递归排[left, div)QuickSort(array, left, div);// 递归排[div+1, right)QuickSort(array, div+1, right);
}

上述为快速排序算法递归实现的主框架,与二叉树前序遍历的规则类似。

快速排序算法可以由多种实现方法,如霍尔法、挖坑法、前后指针法,目前最优的算法是前后指针法,其基本思路是:

  1. 选择数组中的一个元素作为枢轴(一般是第一个元素),其元素为关键值key,而key值最好是数组的中位数(仅在前中后三个元素中取中位数)
  2. 将数组划分为两个子数组,左子数组的元素都小于等于枢轴元素,右子数组的元素都大于等于枢轴元素
  3. 对这两个子数组分别递归调用快速排序算法,继续进行划分和排序
  4. 递归的结束条件是子数组的长度为1或0,即已经有序或为空数组,不需要再进行排序
  5. 通过不断划分和排序,最终实现整体的排序
  6. 在划分过程中,通过比价元素与枢轴元素的大小关系,将元素划分到对应的区域

// 数组开始、中间、结尾三个元素找到中位数,将其作为key值并返回下标
int MidIndex(int* arr, int l, int m, int r)
{if (arr[l] < arr[r]){if (arr[m] < arr[l])return l;else if (arr[m] > arr[r])return r;elsereturn m;}else{if (arr[m] > arr[l])return l;else if (arr[m] < arr[r])return r;elsereturn m;}
}// 前后指针法(快慢指针法)
// 快排每一次递归的核心就是PtrPtr算法返回新的关键字key的下标
// 每一次PtrPtr算法就是为了将小于key的数移到key的左边,将大于key的数移到key的右边
// 当多次进行递归后,数组的有序度已经很高了,所以此时也可以不再递归而是采用直接插入排序
int PtrPtr(int* arr, int begin, int end)
{if (begin >= end)return;int slow = begin;int fast = slow + 1;while (fast <= end){if (arr[fast] < arr[begin] && ++slow != fast)Swap(&arr[slow], &arr[fast]);fast++;}Swap(&arr[begin], &arr[slow]);return slow;	// 返回新的key值下标
}void QuickSort(int* arr, int begin, int end)
{if (begin >= end)return;int mid = (begin + end) / 2;int iKey = MidIndex(arr, begin, mid, end);Swap(&arr[begin], &arr[iKey]);iKey = PtrPtr(arr, begin, end);QuickSort(arr, begin, iKey - 1);QuickSort(arr, iKey + 1, end);
}

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

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

相关文章

集简云数据表新增动态下拉,一键拉取相关数据,快速实现业务场景自动化

为了提升数据表相关场景的数据交互的效率和准确性&#xff0c;本周集简云数据表新增了动态下拉字段&#xff0c;可直接在该字段中关联应用动作获取&#xff0c;无需搭建复杂流程&#xff0c;可搭配按钮使用&#xff0c;直接调用和配置应用动作获取相关字段数据&#xff0c;手动…

MySQL前百分之N问题--percent_rank()函数

PERCENT_RANK()函数 PERCENT_RANK()函数用于将每行按照(rank - 1) / (rows - 1)进行计算,用以求MySQL中前百分之N问题。其中&#xff0c;rank为RANK()函数产生的序号&#xff0c;rows为当前窗口的记录总行数 PERCENT_RANK()函数返回介于 0 和 1 之间的小数值 selectstudent_…

elementui中的tree自定义图标

需求&#xff1a;实现如下样式的树形列表 自定义树的图标以及点击时&#xff0c;可以根据子级的关闭&#xff0c;切换图标 <el-tree :data"treeList" :props"defaultProps"><template #default"{ node, data }"><span class&quo…

Mac安装及配置MySql及图形化工具MySQLworkbench安装

Mac下载配置MySql mysql下载及安装 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 根据自己电脑确定下载x86还是ARM版本的 如果不确定&#xff0c;可以查看自己电脑版本&#xff0c;终端输入命令 uname -a 点击Download下载&#xff0c;可跳过登录注册&…

【论文阅读】Long-Tailed Recognition via Weight Balancing(CVPR2022)

目录 论文使用方法weight decayMaxNorm 如果使用原来的代码报错的可以看下面这个 论文 问题&#xff1a;真实世界中普遍存在长尾识别问题&#xff0c;朴素训练产生的模型在更高准确率方面偏向于普通类&#xff0c;导致稀有的类别准确率偏低。 key:解决LTR的关键是平衡各方面&a…

VRRP协议原理

目录 VRRP的产生单网关的缺陷多网关存在的问题VRRP基本概述VRRP基本结构状态机 VRRP主备备份工作过程VRRP的工作过程如果Master发生故障&#xff0c;则主备切换的过程如果原Master故障恢复&#xff0c;则主备回切的过程 VRRP联动功能 VRRP负载分担工作过程 VRRP的产生 单网关的…

网络体系结构 和网络原理之UDP和TCP

目录 网络分层 一. 应用层 http协议 二. 传输层 1. 介绍 2.UDP协议 (1)组成 (2)细节 3.TCP协议 (1)特性如下链接&#xff1a; (2)组成 (3)特点 三. 网络层 四. 数据链路层 1.介绍 2.以太网协议 3.mac地址和ip地址 五. 物理层 DNS 网络分层 一. 应用层 应用程序 现成的…

《幻兽帕鲁》最全攻略合集!持续更新数据中!幻兽帕鲁下载 幻兽帕鲁爆火

《幻兽帕鲁》是由日本开发商Pocket Pair推出的一款动作冒险生存游戏。这款游戏以丰富的养成内容和高度自由的探索、冒险和建造玩法而受到玩家的好评。虽然《幻兽帕鲁》官方只推出了Windows电脑版本&#xff0c;但是很多Mac电脑玩家利用Crossover&#xff0c;也成功玩上了《幻兽…

Idea设置代理后无法clone git项目

背景 对于我们程序员来说&#xff0c;经常上github找项目、找资料是必不可少的&#xff0c;但是一些原因&#xff0c;我们访问的时候速度特别的慢&#xff0c;需要有个代理&#xff0c;才能正常的访问。 今天碰到个问题&#xff0c;使用idea工具 clone项目&#xff0c;速度特…

Github 2024-01-30 开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-01-30统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4TypeScript项目2Jupyter Notebook项目2HTML项目1Rust项目1C项目1 稳定扩散Web UI 创建周期&…

【Docker】docker安装jenkins

一、执行命令 下载jenkins镜像 #下载jenkins 镜像 docker pull jenkins/jenkins:latest-jdk8 启动jenkins容器 #启动jenkins 容器 #挂载 如果不挂载 每次启动jenkins的配置、插件、用户等信息都没有了 #jenkins_home 包含jenkins配置、插件、用户等信息。 要指定必须配置用…

delphi fmxui 做的一些跨平台app

pascal语音显然已经没落&#xff0c;但delphi还在坚挺着&#xff0c;每年都会发布新版本&#xff0c; 主要是做跨平台应用。 如果你觉得qt qml 写android app 比较麻烦&#xff0c;那可以尝试delphi 12&#xff0c;可以用c builder 尝试 android&#xff0c;ios 开发 下面的…