排序算法——快排
快速排序算法最早是由图灵奖获得者Tony Hoare设计出来的,他在形式化方法理论以 及ALGOL.60编程语言的发明中都有卓越的贡献,是20世纪最伟大的计算机科学家之—。 而这快速排序算法只是他众多贡献中的—个小发明而已。
快速排序(Quick Sort)的基本算法思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可以分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
接下来我们一起来认识一下快排。
霍尔版本
快排共有三种实现方法,最初的一代就是创始人霍尔的版本;

霍尔版本是数组的数,选定数组第一个位置keyi,然后从数组的最右边right=n-1往前一个个找到比keyi位置小的数,接下来从最左边left=0开始,找到第一个比Keyi位置大的数,然后交换刚才找到的右边小的数和左边大的数;接下来继续从右边找小,从左边找大,等到right和left相遇时,停下,此时再交换keyi和left(right)位置的数,那么,比这个key小的数都在key的左边,比Key大的数都在key的右边,再递归0到keyi-1,keyi+1到n-1位置的数,如此下来就可以得到有序的数据。
接下来我们开始实现
int PartSort1(int* a, int left, int right)
{int keyi = left;while (left < right)//left和right相遇时循环停下{while (left<right&&a[right] >= a[keyi])//找小{right--;//right没找到小right--往下走}while (left < right && a[left] <= a[keyi])//找大{left++;//left没找到大left++往下走}Swap(&a[left], &a[right]);//将找到的小的和大的交换位置}Swap(&a[left], &a[keyi]);//最后left和keyi交换位置return left;
}
这是一趟keyi的找大找小过程,一个过程只能确定一个数的位置,我们还需要继续递归keyi的左边和keyi的右边。
int keyi = PartSort1(a, begin, end);
QuickSort(a, begin, keyi - 1);
QuickSort(a, keyi+1, end);
但是什么时候停止呢?当区间只有一个数的时候就需要停止,即begin==end时候return。但是还可能存在只剩区间【0,0】时,此时keyi=1,begin=0,keyi-1=0;keyi+1=2,end=0,发生不存在区间,所以就会停止。

void QuickSort(int* a, int begin,int end)
{if (begin >= end)//{return;}int keyi = PartSort1(a, begin, end);//每次可以确定一个keyi位置,保证不再变动QuickSort(a, begin, keyi - 1);QuickSort(a, keyi+1, end);
}
上述partsort1版本就是霍尔版本的快排。
挖坑法
第二个实现快排的方法是挖坑法

挖坑法呢其实就是也是从a[0]开始,记key=a[0],在最开始处即a[0]处定义一个hole(坑),从右边开始找比key小的值,找到了把a[right]处赋给上一个hole,使right现在的位置为新的hole,再从左边left处找到比key大的值,把a[left]的值赋给上一个hole,使left现在的位置为新的hole,下面我们一起实现。
int PartSort2(int* a, int left, int right)
{int key = a[left];int hole = left;while (left < right){while (left<right && a[right]>key){right--;}a[hole] = a[right];hole = right;while (left<right && a[left]<key){left++;}a[hole] = a[left];hole = left;}a[hole] = key;//相遇后把最后一个hole位置的值给key;return hole;
}
最后返回hole的位置,接下来就和上面一样,QuickSort直接调用PastSort2,然后递归就可以啦。
前后指针法
第三种实现快排的方法是 前后指针法,虽然说是前后指针,其实并不是使用指针,而是两个下标一前一后走。所谓前后指针法就是定义两个下标cur和pre,pre初始为Left,cur是left+1的位置,记录keyi=left的位置的值,cur从当前位置依次往后找比a[keyi]小的值,如果比a[keyi]大或者等于,cur就++往后走,如果小于a[lkeyi]的值,则pre要++,然后交换cur和pre的位置,直到cur走到末尾。最后在交换pre和keyi位置的数值,返回keyi位置就可以了。
下面我们实现
int PartSort3(int* a, int left, int right)
{int pre = left;int cur = left + 1;int keyi = left;while (cur <=right){if (a[cur] >= a[keyi])//找小{cur++;//没找到就++继续往下走}else{pre++;Swap(&a[pre], &a[cur]);//找到了就和++pre位置交换cur++;}}Swap(&a[keyi], &a[pre]);keyi = pre;return keyi;
}
上述写法还可以优化,我们想,如果前几个cur位置都比a[keyi]小的话,也就是先++pre,再交换pre和cur位置,再++cur,可是本来最初cur就比pre提前一个位置,如果一组数据前几个数都是a[cur]<a[keyi]的话就一直是相同的cur位置和pre位置交换。我们可以写成
while (cur<=right)
{if (a[cur] < a[keyi] && ++pre != cur)//只有在pre++!=cur的情况下再交换{Swap(&a[cur], &a[pre]);}cur++;
}
这样就可以减少不必要无意义的交换了。
以上就是三种快排的实现方法,个人而言觉得第三种前后指针法更简便,更容易实现。当然这三种方法并没有本质区别和性能区别,掌握哪种都一样,都能掌握当然是最好的。
#include<stdio.h>
void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}int PartSort1(int* a, int left, int right)//霍尔
{int keyi = left;while (left < right){while (left<right&&a[right] >= a[keyi]){right--;}while (left < right && a[left] <= a[keyi]){left++;}Swap(&a[left], &a[right]);}Swap(&a[left], &a[keyi]);return left;
}
int PartSort2(int* a, int left, int right)//挖坑
{int key = a[left];int hole = left;while (left < right){while (left<right && a[right]>key){right--;}a[hole] = a[right];hole = right;while (left<right && a[left]<key){left++;}a[hole] = a[left];hole = left;}a[hole] = key;return hole;
}
int PartSort3(int* a, int left, int right)//前后指针
{int pre = left;int cur = left + 1;int keyi = left;/*while (cur <=right){if (a[cur] >= a[keyi]){cur++;}else{pre++;Swap(&a[pre], &a[cur]);cur++;}}*/while (cur <= right){if (a[cur] < a[keyi] && ++pre != cur){Swap(&a[cur], &a[pre]);}cur++;}Swap(&a[keyi], &a[pre]);keyi = pre;return keyi;
}
void QuickSort(int* a, int begin,int end)
{if (begin >= end){return;}int keyi = PartSort3(a, begin, end);QuickSort(a, begin, keyi - 1);QuickSort(a, keyi+1, end);
}
int main()
{int a[] = { 5,7,4,3,10,8,2,6,9,1 };QuickSort(a, 0,(sizeof(a) / sizeof(int))-1);return 0;
}
相关文章:
排序算法——快排
快速排序算法最早是由图灵奖获得者Tony Hoare设计出来的,他在形式化方法理论以 及ALGOL.60编程语言的发明中都有卓越的贡献,是20世纪最伟大的计算机科学家之—。 而这快速排序算法只是他众多贡献中的—个小发明而已。 快速排序(Quick Sort)的基本算法思…...
第二节TypeScript 基础语法
1、typescript程序由以下几个部分组成: 模块函数变量语句和表达式注释 2、开始第一个typescript程序 创建一个typescript程序,使之输出“hello typescript”: 代码: var message:string "hello typescript" cons…...
Go、Python、Java、JavaScript等语言的求余(取模)计算
余数符号规则: Go(%): 余数与被除数符号一致 Java(%): 余数与被除数符号一致 JavaScript(%): 余数与被除数符号一致 Python(%)…...
scrapy快加构造并发送请求
scrapy数据建模与请求 学习目标: 应用 在scrapy项目中进行建模应用 构造Request对象,并发送请求应用 利用meta参数在不同的解析函数中传递数据 1. 数据建模 通常在做项目的过程中,在items.py中进行数据建模 1.1 为什么建模 定义item即提前…...
【C++】谈谈深拷贝与浅拷贝
目录 一、浅拷贝 1.定义 2.示例 3.问题 二、深拷贝 1.定义 2.示例 3.优点 三、考虑场景 浅拷贝的考虑 1.性能要求 2.简单地数据结构 3.资源管理 深拷贝的考虑 1.动态内存分配 2.复杂数据结构 3.资源管理 总结 一、浅拷贝 1.定义 浅拷贝是指对对象进行复制时…...
电商API接口如何驱动业务:代码演示与解析
随着电子商务的飞速发展,电商平台的业务逻辑日益复杂,涉及的模块和功能也越来越多。在这个过程中,电商API接口扮演着至关重要的角色。通过API接口,不同的业务模块可以相互通信,实现数据和服务的共享,提高业…...
秋招总结_就业
2020秋招总结 【前言】 以下内容是写给研二学弟学妹们的秋招总结,研一的师弟师妹们如有需要,也可看看。先说一下我为什么要写这个总结: 1、时代在变化,社会在发展,一届有必要给下一届讲一些经验。 2、我平时和你们…...
基于查表法的水流量算法设计与实现
写在前面 本文分享的是一种基于查表法的水流量的算法方案设计与实现,算法简单易懂,主要面向初学者,有两个目的:一是给初学者一些算法设计的思路引导;二是引导初学者学习怎样用C语言编程实现。 一、设计需求 基于“19…...
Python:复制、移动文件到指定文件夹
需要考虑的问题: 指定文件夹是否存在,不存在则创建在指定文件夹中是否存在同名文件,是覆盖还是另存为 import os import shutil import tracebackdef copyfile(srcfile, dstpath, replaceFalse):"""复制文件到指定文件夹par…...
类和对象(中篇)
类的六个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数: 用户没有显式实现,编译器会…...
简单几步完成SVN的安装
介绍以及特点 SVN:Subversion,即版本控制系统。 1.代码版本管理工具 2.查看所有的修改记录 3.恢复到任何历史版本和已经删除的文件 4.使用简单上手快,企业安全必备 下载安装 SVN的安装分为两部分,第一部分是服务端安装&…...
NFS原理详解
一、NFS介绍 1)什么是NFS 它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录。 NFS服务器可以允许NFS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中。 在本地的NFS客户端的机器看来,NFS服务器端共享的目录就好像自己的磁…...
查询后矩阵的和
说在前面 🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是出于什么原因,算法学习需要持续保持。 问题描述 给你一个整数 n 和一个下标从 0 开始的 二维数组 queries ,其中 queries[i] [t…...
Flutter实现丝滑的滑动删除、移动排序等-Dismissible控件详解
文章目录 Dismissible 简介使用场景常用属性基本用法举例注意事项 Dismissible 简介 Dismissible 是 Flutter 中用于实现可滑动删除或拖拽操作的一个有用的小部件。主要用于在用户对列表项或任何其他可滑动的元素执行删除或拖动操作时,提供一种简便的实现方式。 使…...
JDK bug:ciObjectFactory::create_new_metadata:原因完全解析
文章目录 1、问题2.详细日志2.关键日志3.结论4.JDK:bug最终bug链接: 京东遇到过类似bug各位大佬如果有更详细的解答可以留言。 1、问题 服务不通,接口404,查看日志有一下截图,还有一个更详细的日志 2.详细日志 # #…...
【数据结构】并查集的简单实现,合并,查找(C++)
文章目录 前言举例: 一、1.构造函数2.查找元素属于哪个集合FindRoot3.将两个集合归并成一个集合Union4.查找集合数量SetCount 二、源码 前言 需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规…...
2023美团商家信息
2023美团商家电话、地址、经纬度、评分、均价、执照......
0155 - Java 数组
1 数组介绍 数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。 即:数(数据)组(一组)就是一组数据 2 数组的使用 2.1 使用方式一 2.2 使用方式二 3 数组使用注意事项和细节 数组是多个相同类型数据的组合,实现对这些数据…...
Java 语言有哪些特点
Java语言具有以下特点: 简单易学:Java语法相对简单,与C相比更容易上手。 面向对象:Java是一门纯粹的面向对象编程语言,支持封装、继承和多态等面向对象的特性。 平台无关性:Java程序可以在不同的操作系统…...
SAP 特殊采购类50简介----虚拟件
今天我们测试一下特殊类50,也就是我们常说的虚拟件。 虚拟物料是库存中实际不存在的物料清单(BOM)的子装配件,它用于简化物料清单。尽管虚拟物料出现在物料清单中,但生产订单显示制造虚拟物料所需的组件,而不是虚拟物料本身。 我们举个列子,生产的手机是有包装的,有盒子…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...
STL 2迭代器
文章目录 1.迭代器2.输入迭代器3.输出迭代器1.插入迭代器 4.前向迭代器5.双向迭代器6.随机访问迭代器7.不同容器返回的迭代器类型1.输入 / 输出迭代器2.前向迭代器3.双向迭代器4.随机访问迭代器5.特殊迭代器适配器6.为什么 unordered_set 只提供前向迭代器? 1.迭代器…...
中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点
中科院1区顶刊|IF14:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点 当下,免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入,我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...
React、Git、计网、发展趋势等内容——前端面试宝典(字节、小红书和美团)
React React Hook实现架构、.Hook不能在循环嵌套语句中使用 , 为什么,Fiber架构,面试向面试官介绍,详细解释 用户: React Hook实现架构、.Hook不能在循环嵌套语句中使用 , 为什么,Fiber架构,面试向面试官介绍&#x…...
