当前位置: 首页 > news >正文

排序算法——快排

快速排序算法最早是由图灵奖获得者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++;
}

这样就可以减少不必要无意义的交换了。

以上就是三种快排的实现方法,个人而言觉得第三种前后指针法更简便,更容易实现。当然这三种方法并没有本质区别和性能区别,掌握哪种都一样,都能掌握当然是最好的。

快速排序的特性总结:
1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫 快速 排序
2. 时间复杂度: O(N*logN)
3.空间复杂度: O(logN)
源代码
#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世纪最伟大的计算机科学家之—。 而这快速排序算法只是他众多贡献中的—个小发明而已。 快速排序&#xff08;Quick Sort&#xff09;的基本算法思…...

第二节TypeScript 基础语法

1、typescript程序由以下几个部分组成&#xff1a; 模块函数变量语句和表达式注释 2、开始第一个typescript程序 创建一个typescript程序&#xff0c;使之输出“hello typescript”&#xff1a; 代码&#xff1a; var message:string "hello typescript" cons…...

Go、Python、Java、JavaScript等语言的求余(取模)计算

余数符号规则&#xff1a; Go&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 Java&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 JavaScript&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 Python&#xff08;%&#xff09;…...

scrapy快加构造并发送请求

scrapy数据建模与请求 学习目标&#xff1a; 应用 在scrapy项目中进行建模应用 构造Request对象&#xff0c;并发送请求应用 利用meta参数在不同的解析函数中传递数据 1. 数据建模 通常在做项目的过程中&#xff0c;在items.py中进行数据建模 1.1 为什么建模 定义item即提前…...

【C++】谈谈深拷贝与浅拷贝

目录 一、浅拷贝 1.定义 2.示例 3.问题 二、深拷贝 1.定义 2.示例 3.优点 三、考虑场景 浅拷贝的考虑 1.性能要求 2.简单地数据结构 3.资源管理 深拷贝的考虑 1.动态内存分配 2.复杂数据结构 3.资源管理 总结 一、浅拷贝 1.定义 浅拷贝是指对对象进行复制时…...

电商API接口如何驱动业务:代码演示与解析

随着电子商务的飞速发展&#xff0c;电商平台的业务逻辑日益复杂&#xff0c;涉及的模块和功能也越来越多。在这个过程中&#xff0c;电商API接口扮演着至关重要的角色。通过API接口&#xff0c;不同的业务模块可以相互通信&#xff0c;实现数据和服务的共享&#xff0c;提高业…...

秋招总结_就业

2020秋招总结 【前言】 以下内容是写给研二学弟学妹们的秋招总结&#xff0c;研一的师弟师妹们如有需要&#xff0c;也可看看。先说一下我为什么要写这个总结&#xff1a; 1、时代在变化&#xff0c;社会在发展&#xff0c;一届有必要给下一届讲一些经验。 2、我平时和你们…...

基于查表法的水流量算法设计与实现

写在前面 本文分享的是一种基于查表法的水流量的算法方案设计与实现&#xff0c;算法简单易懂&#xff0c;主要面向初学者&#xff0c;有两个目的&#xff1a;一是给初学者一些算法设计的思路引导&#xff1b;二是引导初学者学习怎样用C语言编程实现。 一、设计需求 基于“19…...

Python:复制、移动文件到指定文件夹

需要考虑的问题&#xff1a; 指定文件夹是否存在&#xff0c;不存在则创建在指定文件夹中是否存在同名文件&#xff0c;是覆盖还是另存为 import os import shutil import tracebackdef copyfile(srcfile, dstpath, replaceFalse):"""复制文件到指定文件夹par…...

类和对象(中篇)

类的六个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a; 用户没有显式实现&#xff0c;编译器会…...

简单几步完成SVN的安装

介绍以及特点 SVN&#xff1a;Subversion&#xff0c;即版本控制系统。 1.代码版本管理工具 2.查看所有的修改记录 3.恢复到任何历史版本和已经删除的文件 4.使用简单上手快&#xff0c;企业安全必备 下载安装 SVN的安装分为两部分&#xff0c;第一部分是服务端安装&…...

NFS原理详解

一、NFS介绍 1&#xff09;什么是NFS 它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录。 NFS服务器可以允许NFS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中。 在本地的NFS客户端的机器看来&#xff0c;NFS服务器端共享的目录就好像自己的磁…...

查询后矩阵的和

说在前面 &#x1f388;不知道大家对于算法的学习是一个怎样的心态呢&#xff1f;为了面试还是因为兴趣&#xff1f;不管是出于什么原因&#xff0c;算法学习需要持续保持。 问题描述 给你一个整数 n 和一个下标从 0 开始的 二维数组 queries &#xff0c;其中 queries[i] [t…...

Flutter实现丝滑的滑动删除、移动排序等-Dismissible控件详解

文章目录 Dismissible 简介使用场景常用属性基本用法举例注意事项 Dismissible 简介 Dismissible 是 Flutter 中用于实现可滑动删除或拖拽操作的一个有用的小部件。主要用于在用户对列表项或任何其他可滑动的元素执行删除或拖动操作时&#xff0c;提供一种简便的实现方式。 使…...

JDK bug:ciObjectFactory::create_new_metadata:原因完全解析

文章目录 1、问题2.详细日志2.关键日志3.结论4.JDK&#xff1a;bug最终bug链接&#xff1a; 京东遇到过类似bug各位大佬如果有更详细的解答可以留言。 1、问题 服务不通&#xff0c;接口404&#xff0c;查看日志有一下截图&#xff0c;还有一个更详细的日志 2.详细日志 # #…...

【数据结构】并查集的简单实现,合并,查找(C++)

文章目录 前言举例&#xff1a; 一、1.构造函数2.查找元素属于哪个集合FindRoot3.将两个集合归并成一个集合Union4.查找集合数量SetCount 二、源码 前言 需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后按一定的规…...

2023美团商家信息

2023美团商家电话、地址、经纬度、评分、均价、执照......

0155 - Java 数组

1 数组介绍 数组可以存放多个同一类型的数据。数组也是一种数据类型&#xff0c;是引用类型。 即&#xff1a;数(数据)组(一组)就是一组数据 2 数组的使用 2.1 使用方式一 2.2 使用方式二 3 数组使用注意事项和细节 数组是多个相同类型数据的组合&#xff0c;实现对这些数据…...

Java 语言有哪些特点

Java语言具有以下特点&#xff1a; 简单易学&#xff1a;Java语法相对简单&#xff0c;与C相比更容易上手。 面向对象&#xff1a;Java是一门纯粹的面向对象编程语言&#xff0c;支持封装、继承和多态等面向对象的特性。 平台无关性&#xff1a;Java程序可以在不同的操作系统…...

SAP 特殊采购类50简介----虚拟件

今天我们测试一下特殊类50,也就是我们常说的虚拟件。 虚拟物料是库存中实际不存在的物料清单(BOM)的子装配件,它用于简化物料清单。尽管虚拟物料出现在物料清单中,但生产订单显示制造虚拟物料所需的组件,而不是虚拟物料本身。 我们举个列子,生产的手机是有包装的,有盒子…...

C语言——内存函数的使用与模拟实现

大家好&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流 本文由&#xff1a;残念ing 原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&#xff0c;欢迎各位…...

Mysql索引事务(面试高频)

文章目录 目录 文章目录 前言 一 . 索引 1.1 概念 1.2 作用 1.3 使用场景 1.4 存储引擎 二 . 事务 2.1 事务的概念 2.2 事务四大特性 前言 大家好,今天给大家绍一下mysql索引和事务 一 . 索引 1.1 概念 索引是一种特殊的文件,包含着对数据表中的所有记录的引用指针…...

SpringCloudGateway 3.1.4版本 Netty内存泄漏问题解决

一、 产生的异常 当时是服务器访问不到服务了&#xff0c;上去一看&#xff0c;无法申请资源OutOfDirectMemoryError了&#xff0c;内存级别的东西让人一阵头大&#xff0c;赶紧在线下模拟&#xff0c; 1. 减少分配的堆外内存&#xff0c;打开Netty的监测工具等有助于复现的…...

STM32内部是怎么工作的

STM32是怎么工作的 1 从孩子他妈说起2 早期计算机的组成2.1 五大元件&#xff08;1&#xff09;第一个出场的是电容元件&#xff08;2&#xff09;第二个出场的是二极管&#xff08;3&#xff09;第三个出场的是电阻元件&#xff08;4&#xff09;第四个出场的是电感&#xff0…...

MyBatis的配置文件

目录 MyBatis配置 1.properties标签 2.typeAliases标签 3.Mappers标签 一个最全面的MyBatis配置文件可能会包含各种不同的设置和选项&#xff0c;根据实际情况&#xff0c;可以根据需要添加或删除配置。以下是一个包含各种可能设置的示例。 这个配置文件包含了环境设置、数…...

MCU平台下确定栈空间大小的方法

本文介绍MCU平台下确定栈空间大小的方法。 通常使用IDE开发MCU程序在生成Image文件时&#xff0c;Image文件被划分为代码区&#xff0c;数据区&#xff0c;BSS区&#xff0c;堆区&#xff0c;栈区。其中&#xff0c;代码区&#xff0c;数据区&#xff0c;BSS区空间大小由编译器…...

Flink系列之:SQL提示

Flink系列之&#xff1a;SQL提示 一、动态表选项二、语法三、例子四、查询提示五、句法六、加入提示七、播送八、随机散列九、随机合并十、嵌套循环十一、LOOKUP十二、进一步说明十三、故障排除十四、连接提示中的冲突案例十五、什么是查询块 SQL 提示可以与 SQL 语句一起使用来…...

机器学习算法---聚类

类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统计学检验箱…...

gitlab ci pages

参考文章 gitlab pages是什么 一个可以利用gitlab的域名和项目部署自己静态网站的机制 开启 到gitlab的如下页面 通过gitlab.ci部署项目的静态网站 # build ruby 1/3: # stage: build # script: # - echo "ruby1"# build ruby 2/3: # stage: build …...

Web ML 库的Transformers.js 提供文本转语音功能

JavaScript 库 Transformers.js 提供了类似 Python Transformers 库的功能&#xff0c;设计用于在 Web 浏览器中直接运行 Transformer 模型&#xff0c;而不再需要外部服务器参与处理。在最新的 2.7 版本中&#xff0c;Transformers.js 引入了增强功能&#xff0c;其中包括文本…...

wordpress浮窗播放器/论坛排名

来源&#xff1a;blog.csdn.net/jackJruit/article/details/108287490一.整体功能介绍/***********************************************************实现一个登陆界面1 输出一个登陆界面2 用户名能够实现邮箱验证&#xff0c;regex库&#xff0c;密码要不可见3 进度条的模拟实…...

网站建设的目标用户是/免费正规的接单平台

SELECT DATE_FORMAT( time, %Y-%M ) AS format_time from t_order,%a缩写星期名%b缩写月名%c月&#xff0c;数值%D带有英文前缀的月中的天%d月的天&#xff0c;数值(00-31)%e月的天&#xff0c;数值(0-31)%f微秒%H小时 (00-23)%h小时 (01-12)%I小时 (01-12)%i分钟&#xff0c;数…...

珠海市建设工程质量监督检测站网站/亚马逊站外推广网站

今天学习了内部类的知识&#xff0c;知道内部类是可以持有外部类的this&#xff0c;从而在内部类中可以使用OuterClass.this.medthod()来引用相应外部类方法。但是我写出下代码&#xff0c;可以运行&#xff0c;然而其中的调用逻辑我不是很明白&#xff0c;望赐教&#xff01;p…...

武汉最好的网站建设公司哪家好/seo薪酬

引论 &#xff1a; 在面向对象的程序设计语言中&#xff0c;多态&#xff08;polymorphic&#xff09;是继数据抽象和继承之后的第三种基本特性。 多态通过分离“做什么”和“怎么做”&#xff0c;从另一角度将接口和实现分离开来。多态不但能够改善代码的组织结构和可读性&…...

长沙百度做网站多少钱/推广软件赚钱的平台

手机上有好用的时钟APP&#xff0c;时钟软件哪个好用? 每个人的手机屏幕都有着自己独特的设计&#xff0c;而时钟软件能够为用户的手机再增添一些风采和魅力&#xff0c;更有专为来年人设计的大字体桌面时钟&#xff0c;更加的清晰直观&#xff0c;各种特色的桌面时钟app中都有…...

温州市网页制作项文静/关键词优化教程

今天在解决爬虫对加密参数的分析时&#xff0c;需要使用到base64解码。但是过程中出现了TypeError&#xff1a;Incorrect padding的错误提示。以下是解决方法&#xff0c;以便查阅。 其实正常使用base64是不会出现问题的&#xff0c;就比如下面的代码。 1 #!usr/bin/env pytho…...