快速排序详解——多种实现方式

快速排序

快速排序是一种交换排序,是基于二叉树结构的交换排序方法,基本思想如下:

任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

将区间按照基准值划分为左右两半部分的常见方式为:

hoare版本实现快速排序

hoare版本实现快排的方式为:如果假定key基准值为最左边,然后应该从右边开始向左查看,遇到大于基准值key的right—,反之停在这个位置,再让左手left开始找大于key的元素,遇到之后也停止,最后两者交换,完成这一趟循环之后(left和right两者相遇)key是大于相遇位置的元素的,最后交换着这两个元素,将相遇位置下表赋值给key,再递归

代码实现:

//抽离Swap交换函数
void Swap(int* a,int* b)
{int tmp=*a;*a=*b;*b=tmp;
}void QuickSort(int a[], int left, int right)
{if (left >= right) return;int begin = left;int end = right;int keyi = left;//初始化keyi基准值的下标while (left < right){//以左手为基准值,那么就要从右手开始while (left<right && a[right]>a[keyi]) {--right;}while (left < right && a[left] < a[keyi]){++left;}//然后找到位置之后,进行交换、Swap(&a[left], &a[right]);}//整个一趟交换完毕之后,进行交换key和left的位置Swap(&a[keyi], &a[left]);//left 和right 的运动的,begin和end都是为了保留原来的left和right,为了最后的递归keyi = left;QuickSort(a, begin, keyi - 1);QuickSort(a, keyi + 1, end);
}

这是第一个版本,我们比较好理解,这个本质上就是二叉树的结构演化出来的快速排序,所以,我们知道一点,当key保持在最中间位置的时候,算法是最优的

如果说对于有序数组,实际上key基准值再从最左边或者最右边开始,会导致key永远在最左边或者右边,实际上是和冒泡排序差不多,所以这个时候,就是最坏的情况,时间复杂度为O(n2)

上述方法的快排竟然对于有序的情况是最坏的情况,所以我们需要对于这个改正,改变的是key基准值的下标的位置,所以下面两个方法可以对于上述快排进行优化。

优化快排算法方式

有两种方式,第一种是获取随机keyi下标,另一种是三数取中方法

第一种随机值法

//使用rand()函数
void getKeys(int* a,int left,int right)
{int randi=left+rand()%(right-left);Swap(&a[left],a[randi]);
}
//剩下的还是那些
将keyi=left  然后while循环即可,下面不变

这一种方法是比较好写的方法,比较简单方便

第二种三数取中方法

三数是指left、right、mid,取得不是最大不是最小,恰好处于最中的为元素下标

//这个方法返回的是一个下标,取得keyi的数值之后,还是需要跟keyi交换
int getmidinum(int a[],int left,int right)
{int mid=(left+right)/2;//获得中间值if(a[left]<a[mid]){if(a[mid]<a[right]){return mid;}else if(a[left]>a[right]){return left;}else{return right;}}else {if(a[mid]>a[right]){return mid;}else if(a[left]<a[right]){return left;}else{return right;}}
}
//然后返回的数值赋值给midi
int midi=getmidinum(......);
if(midi!=left)  //判别是否是同一个位置,实际上无所谓这个
Swap(&a[left],&a[midi]);

挖坑法实现快排

挖坑法,实际上和hoare版本差不多的,只是多一个坑的概念

挖坑法,先设定key基准值,形成一个坑位(设定一个变量hole表示坑)然后从右开始找到小于key的数值,然后将这个数值放在坑里,然后赋值hole这个位置,表示新的坑,再左边开始找到大于key的位置,再次放在hole里,继而hole更新为这个左边的位置

类似于上述的过程

void QuickSort1(int a[],int left ,int right)
{if(left>=right) return;int begin=left,end=right;getKeys(a,left,right);int hole =left;int keyi = left;//初始化keyi基准值的下标while (left < right){//以左手为基准值,那么就要从右手开始while (left<right && a[right]>=a[keyi]) {--right;}a[hole]=a[right];hole=right;while (left < right && a[left] <= a[keyi]){++left;}a[hole]=a[left];hole=left;}//整个一趟交换完毕之后,进行交换key和left的位置a[hole]=a[keyi];QuickSort2(a, begin, hole - 1);QuickSort2(a, hole + 1, end);
}

快慢指针实现快排

使用两个指针cur和pre来实现快速排序

void QuickSort(int a[],int left,int right)
{if(left>=right) return;int midi=getmininum(a,left,right);Swap(&a[left],&a[midi]);int keyi=left;int prev=left;int cur=left+1;while(cur<=right){if(a[cur]>a[keyi]&&++prev!=cur){Swap(&a[cur],&a[prev]);}++cur;}Swap(&a[prev],&a[keyi]);keyi=prev;QuickSort(a,left,keyi-1);QuickSort(a,keyi+1,right);    
}

Acwing提供的快排方法

快速排序的优化,对于快速排序的优化还有一种,因为快速排序的基于二叉树结构的,所以在最后一层或者是倒数几层递归次数很多,如果说对于这样的层数进行优化,使得非递归解决排序,会提高不少效率

void QuickSort(int a[],int left,int right)
{if(left>=right) return;int key=a[left];int i=left-1;int j=right+1;while(i<j){do{++i;}while(a[i]<key);do{--j;}while(a[j]>key);if(i<j){Swap(&a[i],&a[j]);}}QuickSort(a,l,j);QuickSort(a,j+1,r);
}

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

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

相关文章

亚信安慧AntDB:可靠的数据处理和存储工具

AntDB数据库具有高性能、高可用性和高扩展性等诸多优点&#xff0c;能够高效应对庞大数据存储和处理需求&#xff0c;同时保障数据的安全和稳定。不论是企业级业务系统还是政府信息管理平台&#xff0c;AntDB都能够轻松胜任&#xff0c;展现出其强大的适应能力和可靠性。 其强…

数据量较小的表是否有必要添加索引问题分析

目录 前言一、分析前准备1.1、准备测试表和数据1.2、插入测试数据1.3、测试环境说明 二、具体业务分析2.1、单次查询耗时分析2.2、无索引并发查询服务器CPU占用率分析2.3、添加索引并发查询服务器CPU占用率分析 三、总结 前言 在一次节日活动我们系统访问量到达了平时的两倍&am…

【小沐学GIS】GDAL库安装和使用(C++、Python)

文章目录 1、简介2、下载和编译&#xff08;C&#xff09;2.1 二进制构建2.1.1 Conda2.1.2 Vcpkg 2.2 源代码构建2.2.1 nmake.opt方式构建2.2.2 generate_vcxproj.bat方式构建 2.3 命令行测试2.3.1 获取S57海图数据 2.4 代码测试2.4.1 读取tiff信息 3、Python3.1 安装3.2 测试3…

零基础入门篇④ 初识Python(注释、编码规范、关键字...)

Python从入门到精通系列专栏面向零基础以及需要进阶的读者倾心打造,9.9元订阅即可享受付费专栏权益,一个专栏带你吃透Python,专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇…学习不断,持续更新,火热订阅中🔥专栏订阅地址 👉Python从…

C语言:通讯录管理系统的实现

如何来实现通信录呢&#xff1f; 人的信息包括&#xff1a;名字年龄性别电话地址&#xff0c;等来表示 想要实现的功能&#xff1a; 1、默认存放100个人的信息 2、增加联系人信息 3、删除指定联系人信息 4、查找联系人信息 5、修改联系人信息 6、对联系人信息排序 7、显示联系人…

C语言 | Leetcode C语言题解之第110题平衡二叉树

题目&#xff1a; 题解&#xff1a; int height(struct TreeNode* root) {if (root NULL) {return 0;}int leftHeight height(root->left);int rightHeight height(root->right);if (leftHeight -1 || rightHeight -1 || fabs(leftHeight - rightHeight) > 1) {…

Fortran: select type

Fortran: select type 实现类似C的template函数功能 module M_reduceuse mpi_f08interface reducemodule procedure reduce_scalar,reduce_arrayend interface reducecontains!!https://docs.open-mpi.org/en/v5.0.x/man-openmpi/man3/MPI_Reduce.3.htmlsubroutine reduce_ar…

Android硬件渲染环境初始化

Android硬件渲染环境初始化 一.硬件加速渲染的开启1.ThreadedRenderer的初始化2.RenderProxy的创建 二.RenderProxy中组件的初始化1.RenderThread的创建2.CanvasContext的创建3.DrawFrameTask的初始化 三.RenderThread的启动1.RenderThread中组件的初始化2.RenderThread中任务的…

arXiv AI 综述列表(2024.05.20~2024.05.24)

公众号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 每周末更新&#xff0c;完整版进群获取。 Q 群在群文件&#xff0c;VX 群每周末更新。 目录 1. Beyond Traditional Single Object Tracking: A …

基于yolov2深度学习网络的昆虫检测算法matlab仿真,并输出昆虫数量和大小判决

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022A 3.部分核心程序 .......................................................... for i 1:12 % 遍历结…

播兔短剧模板:图鸟UI在前端短剧平台中的应用与实践

一、引言 随着移动互联网的快速发展&#xff0c;短剧平台因其短小精悍、内容丰富的特点&#xff0c;逐渐成为用户休闲娱乐的新宠。为了满足短剧平台对前端技术的需求&#xff0c;图鸟播兔短剧模板应运而生。该模板基于图鸟UI进行开发&#xff0c;采用纯前端技术&#xff0c;支…

layui-左侧递归菜单-js实现

完整代码 两种下拉风格 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title>…

【C语言回顾】文件操作

前言1. 文件打开模式2. 示例代码2.1 打开和关闭文件2.2 读写文件2.3 二进制文件操作 结语 #include<GUIQU.h> int main { 上期回顾: 【C语言回顾】动态内存管理 个人主页&#xff1a;C_GUIQU 专栏&#xff1a;【C语言学习】 return 一键三连; } 前言 各位小伙伴大家好&…

美国空军出版物:网络空间作战

这份文件是《AIR FORCE DOCTRINE PUBLICATION 3-12: CYBERSPACE OPERATIONS》&#xff0c;即美国空军教义出版物3-12&#xff0c;关于网络空间作战。 该文件详细阐述了美国空军在网络空间领域的组织、规划、执行、评估以及相关的政策、角色和责任。 以下是其核心内容的概述&a…

搜索引擎索引是什么

搜索引擎索引是搜索引擎中的关键组件&#xff0c;用于存储和管理网页、文档、图片等信息&#xff0c;并提供快速的检索功能。索引包括索引基础、单词词典、倒排列表、建立索引、动态索引、索引更新策略、查询处理、多字段索引、短语查询和分布式索引。 索引基础&#xff1a;索…

特定情况下docker run --restart=always重启失效的情况

特定情况下解决cicd中docker run --restartalways重启失效的情况_c 执行exit后 restartalways失效-CSDN博客

分享:怎么才能保证大数据查询的准确性?

随着大数据应用到金融风控领域&#xff0c;大数据越来越重要了&#xff0c;很多朋友在查大数据的时候都会遇到一个问题&#xff0c;那就是自己查询的大数据什么信息都没有&#xff0c;要么就是很少&#xff0c;这是什么原因呢?要怎么才能保证大数据查询的准确性呢?下面小编就…

给JTextArea添加右键菜单

给JTextArea添加右键菜单 package jTextarea;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent;import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import jav…

Java进阶学习笔记3——static修饰成员方法

成员方法的分类&#xff1a; 类方法&#xff1a;有static修饰的成员方法&#xff0c;属于类&#xff1a; 成员方法&#xff1a;无static修饰的成员方法&#xff0c;属于对象。 Student类&#xff1a; package cn.ensource.d2_staticmethod;public class Student {double scor…

双拼打字,可以尝试这个练习平台

本文将介绍由本人开发的双拼练习平台打字侠&#xff0c;以及一些对新手学习双拼的建议。课程一共233课&#xff0c;共分为两大部分&#xff1a; 韵母键位&#xff0c;主要练习双拼中韵母对应的键盘键位&#xff0c;同时提供可视化的键盘指法示意图。 实战练习&#xff0c;同时…