【排序】快速排序实现
目录
一、快速排序是什么?
二、左右指针法
1.实现原理
2.代码如下:
三、挖坑法
1.实现原理
2.代码如下:
四、前后指针法
1.实现原理
2.代码如下:
五、三数取中
1.实现思想
2.代码如下:
3.使用方法
总结
前言
快排是公认的排序效率之王,加上三数取中与小区间优化更是无人能敌。
一、快速排序是什么?
快排分为三种实现方式:
①左右指针法
②挖坑法
③前后指针法
其中左右指针与挖坑法实现原理差不多一样:(只是挖坑法多创建一个临时变量存储坑中的数据)它们俩都是选大的的通过自己的方式放在后面,选出小的通过自己的方式放前面,通过递归就可将整个数组进行排序。
前后指针法同样是选大的放后面,选小的放前面,但是与上面两个不同的是它只从一头开始遍历。
二、左右指针法
1.实现原理
① 定义两个指针,一个从左边遍历,一个从右边遍历。
② 定义一个key值用来做比较的基准值。
③ 如果key是最左边的值,那么就让right先向左找小值,反之,就让left先找大值。
目的:在left与right相遇时,在与key值交换时能够交换大值(小值),否则会出现数据错误。
④ 假定key值定义为最左边的数字,
right向左走找比key值大的数据,找到后停下,
left向右走找比key值小的数据,找到后停下,
此时交换left与right对应的值,循环往复直至left与right相遇。
⑤ 相遇后,将相遇点与keyi对应的数据进行交换,此时数组将会达到key左边的数字都小于key,右边的数字都大于key,后续通过递归可实现整个数组的排序。
2.代码如下:
#include <stdio.h>void swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
// 左右指针法
void QuickSort1(int* arr, int begin, int end)
{if (begin >= end){return;}int left = begin;int right = end;int keyi = left;while (left < right){// right向左找小while (left < right && arr[right] >= arr[keyi]){right--;}while (left < right && arr[left] <= arr[keyi]){left++;}// key的大值与小值进行换位swap(&arr[left], &arr[right]);}// 左右指针相遇,与key换位int meeti = left;swap(&arr[meeti], &arr[keyi]);QuickSort1(arr, begin, meeti - 1);QuickSort1(arr, meeti + 1, end);
}
int main()
{int arr[] = { 5,3,6,9,8,7,2,0,1,4 }; size_t len = sizeof(arr) / sizeof(arr[0]);QuickSort1(arr, 0, len - 1);return 0;
}
三、挖坑法
1.实现原理
挖坑法与左右指针法大致相同。
① 选出一个key值,并将其所在的位置定为坑(坑可被覆盖 -> 放数据,坑中的数据被保存在了key中)
② 定义两个指针,一个从左边遍历,一个从右边遍历。
③同左右指针法相同,
如果key是最左边的值,那么就让right先向左找小值,反之,就让left先找大值。
目的:在left与right相遇时,在与key值交换时能够交换大值(小值),否则会出现数据错误。
④ 假定key值定义为最左边的数字:
right找到比key值大的数据停下,将此数入坑,同时right所在的位置变为新坑;
left向右走找比key值小的数据,找到后停下,将此数入坑,同时left所在的位置变为新坑;
循环此过程直至两指针相遇。
⑤ 将key值入坑,此时数组将会达到key左边的数字都小于key,右边的数字都大于key,后续通过递归可实现整个数组的排序。
2.代码如下:
// 挖坑法
void QuickSort2(int* arr, int begin, int end)
{if (begin >= end){return;}int left = begin;int right = end;int key = arr[left];int pivot = left;while (left < right){// right向左找小while (left < right && arr[right] >= key){right--;}// 入坑,更新坑位arr[pivot] = arr[right];pivot = right;// left向右找大while (left < right && arr[left] <= key){left++;}arr[pivot] = arr[left];pivot = left;}// 相遇,key值入坑arr[pivot] = key;QuickSort2(arr, begin, pivot - 1);QuickSort2(arr, pivot + 1, end);
}// 挖坑法
void QuickSort2(int* arr, int begin, int end)
{if (begin >= end){return;}int left = begin;int right = end;int key = arr[left];int pivot = left;while (left < right){// right向左找小while (left < right && arr[right] >= key){right--;}// 入坑,更新坑位arr[pivot] = arr[right];pivot = right;// left向右找大while (left < right && arr[left] <= key){left++;}arr[pivot] = arr[left];pivot = left;}// 相遇,key值入坑arr[pivot] = key;QuickSort2(arr, begin, pivot - 1);QuickSort2(arr, pivot + 1, end);
}
int main()
{int arr[] = { 5,3,6,9,8,7,2,0,1,4 }; size_t len = sizeof(arr) / sizeof(arr[0]);QuickSort1(arr, 0, len - 1);return 0;
}
四、前后指针法
1.实现原理
① 定义两个指针,一前(cur)一后(prev)。
② 定义一个key值,用来作为单趟排序的基准值。
② 让前面的指针继续向前遍历,如果找到比key值小的,++prev后与其交换。
③ 重复②直至cur到达数组末尾,交换prev与keyi对应的数据。
④ 此时数组将会达到key左边的数字都小于key,右边的数字都大于key,后续通过递归可实现整个数组的排序。
2.代码如下:
// 前后指针法
void QuickSort3(int* arr, int begin, int end)
{if (begin >= end){return;}int left = begin;int right = end;int key = arr[left];int prev = left;int cur = prev + 1;while (cur <= end){if (arr[cur] < key && ++prev != cur)// 减少不必要的swap{swap(&arr[prev], &arr[cur]);}++cur;}swap(&arr[prev], &arr[begin]);QuickSort3(arr, begin, prev - 1);QuickSort3(arr, prev + 1, end);
}int main()
{int arr[] = { 5,3,6,9,8,7,2,0,1,4 }; size_t len = sizeof(arr) / sizeof(arr[0]);QuickSort3(arr, 0, len - 1);return 0;
}
五、三数取中
1.实现思想
当待排序数组本来是逆序时,快排效率将降到最低,为O(N2),每次都许哟啊对每个数进行交换位置2次,所以产生了三数去中的方法:
取得数组最开始、最末尾、最中间中的中间值来平衡key值。
2.代码如下:
// 三数取中
int GetMidIndex(int* arr, int begin, int end)
{int mid = (end - begin) / 2 + begin;if (arr[begin] < arr[end]){// begin < end < midif (arr[mid] > arr[end]){return end;}// mid < begin < endelse if (arr[mid] < arr[begin]){return begin;}// begin < mid < endelse{return mid;}}// end < beginelse{// mid < end < beginif (arr[mid] < arr[end]){return end;}//end < begin < midelse if(arr[mid] > arr[begin]){return begin;}else{return mid;}}
}
3.使用方法
在取key值时仍可继续取left位置的值,但是在此之前做一次交换即可。
int index = GetMidIndex(arr, begin, end);swap(&arr[index], &arr[left]);int key = arr[left];
总结
抓住快排的思想要点,加上调试即可快速实现出排序算法。
相关文章:
【排序】快速排序实现
目录 一、快速排序是什么? 二、左右指针法 1.实现原理 2.代码如下: 三、挖坑法 1.实现原理 2.代码如下: 四、前后指针法 1.实现原理 2.代码如下: 五、三数取中 1.实现思想 2.代码如下: 3.使用方法 总结…...
YOLOv5/v7 Flask Web 车牌识别 | YOLOv7 + EasyOCR 实现车牌识别
YOLOv7 Flask Web 车牌识别图片效果展示 本篇博文只包含源码以及使用方式,目前不同提供详细开发教程。 YOLOv7 Flask Web 车牌识别视频效果展示 YOLOv7 + EasyOCR 实现车牌识别 什么是Flask? 简介 Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更…...
【Opencv实战】几十年前的Vlog火了:黑白老照片如何上色?这黑科技操作一定要知道,复原度超高,竟美的出奇~(图像修复神级代码)
导语 哈喽大家好呀!我是每天疯狂赶代码的木木子吖~情人节快乐呀! 所有文章完整的素材源码都在👇👇 粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。 我们都知道,有很多经典的老照片…...
React源码分析(一)Fiber
前言 本次React源码参考版本为17.0.3。 React架构前世今生 查阅文档了解到, React16.x是个分水岭。 React15及之前 在16之前,React架构大致可以分为两层: Reconciler: 主要职责是对比查找更新前后的变化的组件;R…...
小樽 C++指针—— (壹) 指针变量
(壹) 指针变量 一、指针的概念与定义 二、给指针变量p赋值 三、指针变量的的、-运算 四、无类型指针 五、多重指针 C (壹) 指针变量 小明想把从李华家借来的书——《CCF中学生计算机程序设计》还给李华,但李华不在家,于是把书放到书架第3层的最右边…...
java 代码块 万字详解
概述 : 特点 : 格式 : 情景 : 细节 : 演示 : 英文 : //v,新版编辑器无手动添加目录的功能,PC端阅读建议通过侧边栏进行目录跳转;移动端建议用PC端阅读。😂一、概述 :代码块,也称为初始化块,属于类中的成员&…...
杂项-图片隐写
图片隐写的常见隐写方法: 三基色:RGB(Red Green Blue) 图片文件隐写 1.Firework 使用winhex打开文件时会看到文件头部中包含firework的标识,通过firework可以找到隐藏图片。 使用场景:查看隐写的图片文件…...
【高性价比】初学者入门吉他值得推荐购买的民谣单板吉他品牌—VEAZEN费森吉他
“在未知的世界里,我们是一群不疲不倦的行者,执念于真善美,热衷于事物的极致。我们抽丝剥茧,不断地打败自己,超越自己,我们无所畏惧终将成为巨人。”这是VEAZEN吉他官网首页上很明显的一段话,也…...
2023年浙江交安安全员考试题库及答案
百分百题库提供交安安全员考试试题、交安安全员考试真题、交安安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 50.根据《建设工程安全生产管理条例》第65条规定,施工单位有下列()行…...
【新】华为OD机试 - 跳格子(Python)
跳格子 题目 地上共有 N 个格子,你需要跳完地上所有的格子, 但是格子间是有强依赖关系的,跳完前一个格子后, 后续的格子才会被开启,格子间的依赖关系由多组 steps 数组给出, steps[0] 表示前一个格子, steps[1] 表示 steps[0] 可以开启的格子: 比如 [0,1] 表示从跳完第…...
乡村能做社区团购吗?怎么做?我走访调查后发现机会很大
乡村能做社区团购吗?怎么做?我走访调查后发现机会很大#深度触网 #社区团购 #乡村振兴##乡村旅游##县域经济##市场经济##农文旅产业振兴研究院#乡村旅游能带动农产品加工业、服务业、商贸业等相关联产业的发展 乡村能做社区团购吗?怎么做&…...
态路小课堂丨下一代数据中心100G接口第二篇——SFP-DD封装
100G光模块根据封装模式可分为QSFP28、CXP、CFP、CFP2、FCP4、DSFP和SFP-DD等。态路小课堂之前已经大量介绍了相关内容(。 态路小课堂丨下一代数据中心100G接口——DSFP态路小课堂丨100G解决方案-425G NRZ光模块态路小课堂丨什么是100G QSFP28单波光模块?…...
状态栏和导航栏高度获取
/*** 获取导航栏高度*/public static int getNavigationBarHeight(Context context){int navigationBarHeight 0;int resourceId context.getResources().getIdentifier("navigation_bar_height", "dimen", "android")if (resourceId > 0) {…...
插曲:第一桶金 1w 的来由
因为前天跟同事聊天,发现有个比较严重的认知,就是关于赚钱思维。 同事反馈说工作十来年,却没有接过私活,这里话分两头,有可能私 活钱少,但他给我的理由是:私活太麻烦,有时候不敢接&a…...
中国甲基异丁基甲醇行业头部企业市场占有率及排名调研报告
内容摘要 本文调研和分析全球甲基异丁基甲醇发展现状及未来趋势,核心内容如下: (1)全球市场总体规模,分别按销量和按收入进行了统计分析,历史数据2018-2022年,预测数据2023至2029年。 …...
streamlit自定义组件教程和组件开发环境配置
About create your own component: you can follow this tutorial streamlit tutorial 重要!以下步骤都是在教程的基础上更改的。这个教程做的很棒。 Component development environment configuration: 根据文章 https://streamlit-com…...
Windows CMD常用命令
目录 【打开CMD命令】 【网络测试命令】 ipconfig------查看本机网卡信息 ping------测试网络是否通畅 tracert------追踪路由,也可以用来查看网络连通性 telnet------查看目的主机ip的端口号是否开放 tcping------查看目的主机ip的端口号是否开放 【关于路…...
ChIP-seq 分析:数据比对(3)
读取 reads(二者含义相同,下文不做区分)1. ChIPseq reads 比对 在评估读取质量和我们应用的任何读取过滤之后,我们将希望将我们的读取与基因组对齐,以便识别任何基因组位置显示比对读取高于背景的富集。 由于 ChIPseq…...
并非从0开始的c++之旅 day2
并非从0开始的c之旅 day2一、变量1、 变量名的本质二、程序的内存分区模型1、内存分区运行之前运行之后三、栈区注意事项四、堆区1、堆区使用2、堆区注意事项五、全局变量静态变量1、静态变量2、全局变量六、常量1、全局const常量2、局部const常量七、字符串常量一、变量 既能…...
Linux进阶(Shell编程学习一)
由于shell脚本在java项目运维方面极其重要,比如服务的启动脚本,日志的分割脚本,文件的管理脚本大多都是shell脚本去实现的。所以作为java开发者懂linux的基本命令,会基本的shell编程是必要的。 Shell 是一个用 C 语言编写的程序&…...
AI时代求职必懂的8大核心技术陷阱,最强就业指南
AI求职八股文大变革:不会这些新技术,下一个淘汰的就是你!(100个夺命真题解析)💀 警告: 如果你还在背那些“HashMap底层原理”和“三次握手四次挥手”,请立刻停止!AI面试官…...
鸿蒙 HarmonyOS 6 | 网络请求超时重试与弱网适配深度解析
文章目录前言一、网络请求的底层机制与超时配置二、超时重试的核心原理与代码实现三、架构优化策略总结前言 弱网环境下的网络波动极易导致应用与服务端断开连接。这不仅影响软件可用性,更是底层技术架构必须解决的核心问题。鸿蒙 6 在网络请求模块进行了底层架构强…...
中考真题资源合集
2024版《万唯中考真题分类》合集 文件大小: 2.2GB内容特色: 2024版万唯中考真题按考点分类,全科覆盖适用人群: 初三学生、教师、家长陪读备考核心价值: 刷透真题,精准查漏补缺,冲刺高分下载链接: https://pan.quark.cn/s/73347caeee74 2026…...
ROS小车导航避坑指南:move_base + AMCL + TEB 配置全流程与常见问题排查
ROS导航实战:从AMCL定位到TEB路径规划的避坑手册 当你的机器人在地图上疯狂转圈、对着墙壁直冲或者干脆拒绝移动时,导航栈的调试就变成了充满挫败感的解谜游戏。本文将带你穿越move_base、AMCL和TEB配置的迷雾森林,用工程化的排查思路解决那些…...
工业相机图像采集处理:从 RAW 数据到 AI 可读图像,附basler相机 C#实战代码
工业相机图像采集处理:从 RAW 数据到 AI 可读图像,附basler相机 C#实战代码前言: 做工业视觉的兄弟们都遇到过这种场景: 用 Basler Pylon SDK 自带的 Converter 转图,代码是简洁了,但一上高帧率(…...
4大突破:面向全场景的聊天应用UI设计方案
4大突破:面向全场景的聊天应用UI设计方案 【免费下载链接】ui Simple UI examples from my social media 项目地址: https://gitcode.com/GitHub_Trending/ui1/ui 现代聊天应用如何在视觉体验与功能实用性之间取得平衡?GitHub推荐项目精选中的聊天…...
OpenClaw低配适配:nanobot在4GB内存设备运行技巧
OpenClaw低配适配:nanobot在4GB内存设备运行技巧 1. 为什么要在低配设备上运行OpenClaw? 去年夏天,我在整理一台2015年的老笔记本时突发奇想:这台只有4GB内存的"古董"能否跑得动OpenClaw?当时市面上大多数…...
文旅直播助农成新风口!巨有科技数智工具,复刻董宇辉“阅山河”助农模式
当下,文旅直播助农成为乡村振兴与文旅融合的新风口,董宇辉“阅山河”模式开创“边走边播、以文促农”的新范式,通过沉浸式文旅直播,实现“文旅引流农产品变现”的双向赋能,带动多地农产热销与文旅发展,但CS…...
学术PDF处理流水线:OpenClaw+Qwen3-32B-Chat镜像实现论文精读
学术PDF处理流水线:OpenClawQwen3-32B-Chat镜像实现论文精读 1. 为什么需要自动化论文精读工具 作为一名经常需要阅读大量学术文献的研究者,我长期被三个问题困扰:一是PDF文档的信息密度太高,逐字阅读耗时耗力;二是跨…...
自动化代码审查:OpenClaw+nanobot分析Git提交差异
自动化代码审查:OpenClawnanobot分析Git提交差异 1. 为什么需要轻量级代码审查方案 作为独立开发者,我经常面临一个困境:既希望保持代码质量,又不愿意搭建复杂的CI/CD系统。传统的代码审查工具要么需要企业级部署,要…...
