三路快排(基于三指针单趟排序的快速排序)+快排时间复杂度再分析
目录
一.前言
二. 三路快排
😍算法思想:
😍算法实现步骤:
😍三指针单趟排序的实现:
😍非递归快排完全体:
🤔与C标准库里的快排进行对比测试:
三.快排时间复杂度再分析
一.前言
http://t.csdn.cn/mz8dg
http://t.csdn.cn/mz8dghttp://t.csdn.cn/1TqDp
http://t.csdn.cn/1TqDp
- 😄关于快排的基本思想和实现及其优化
- 😄利用双指针单趟排序实现的快速排序有一个无法避免的缺陷:当待排序序列中有大量(或全部)元素相同时,快排的时间复杂度会升阶为O(N^2),此时快排的递归树呈线型结构,递归的深度为O(N),时间消耗和空间消耗都非常巨大:
- 😄为了避免这种情况出现,就需要重新设计一下快排的单趟排序,目的在于:当待排序序列中存在大量相同元素时,减小快排递归树的深度
二. 三路快排
😍算法思想:
- 🤪三路快排的单趟排序是利用三指针算法来实现的
- 🤪其基本思想是利用三个指针将数组从左到右划分为三个部分,第一部分中所有元素都比key小,第二部分中所有元素都等于key,第三部分中所有元素都大于key
- 🤪后续就可以对数组第一部分和第三部分进行分治,数组的第二部分所有元素已经处于它们在有序序列中的最终位置,无须再进行处理
- 🤪三路快排的边界条件有点折磨人
😍算法实现步骤:
- 🤪三个指针的初始位置如图所示
- 🤪left是待排序区间的左边界,right是待排序区间的右边界,待排序区间为闭区间
- 🤪算法实现思路:
- 🤪利用midi指针来遍历待排序序列,遍历限制条件为:midi<greater.
- 😝若arr[midi]比key大,令grater指针减一,并将arr[midi]交换到[greater,right]区间中,midi指针不动
- 😝若arr[midi]比key小,令small指针加一, 并将arr[midi]交换到[left+1,small]区间中,midi指针向前走一步
- 😝若arr[midi]与key相同,midi指针向前走一步,其余指针不动,目的是将等于key元素的arr[midi]"括入"[small+1,midi)区间中
- 😝重复上述过程直到midi指针和geater指针相遇,算法gif:
- 😝经过上述过程,最终[left+1,small]区间中的所有元素一定比key小,[greater,right]区间中的所有元素一定比key大,[small+1,midi)区间中的所有元素一定等于key:
- 😝同时注意,迭代过程结束后,small最终指向的元素一定小于key,所以最后一步就是将arr[small]和arr[left]进行交换,于是数组就被划分成了三个部分:
- 😝接下来就可以对区间[left,small-1]和区间[greater,right]进行分治并形成递归完成快速排序
😍三指针单趟排序的实现:
void QuickSort(int* arr, int left, int right) {assert(arr);int key = left;int midi = left + 1;int small = left;int greater = right + 1;while (midi < greater){if (arr[midi] < arr[key]) //将arr[midi]交换到[left + 1, small]区间中,同时注意small位置的元素一定比key元素小{++small;if (small != midi){swap(&arr[small], &arr[midi]);}++midi;}else if (arr[midi] > arr[key]) //将arr[midi]交换到[greater,right]区间{--greater;swap(&arr[midi], &arr[greater]);}else{++midi; //将等于key元素的arr[midi]"括入"[small+1,midi)区间中}}swap(&arr[small], &arr[key]); //small最终指向的元素一定小于key }接下来再进行分治递归并给出递归出口完成快速排序:
😍非递归快排完全体:
- 😝同时辅以三数取中优化
void swap(int* e1, int* e2) {assert(e1 && e2);int tem = *e1;*e1 = *e2;*e2 = tem; }//三数取中优化 int GetMid(int* arr,int left,int right) {int mid = left + ((right - left) >> 2); //在arr[left],arr[mid],arr[right]三者中取中间值作为key,返回key的下标if (arr[left] < arr[right]){if (arr[left] < arr[mid] && arr[mid] < arr[right]){return mid;}else if (arr[mid] > arr[right]){return right;}else{return left;}}else{if (arr[left] > arr[mid] && arr[mid] > arr[right]){return mid;}else if (arr[mid] > arr[left]){return left;}else{return right;}} } void QuickSort(int* arr, int left, int right) {if (left >= right) //递归出口{return;}assert(arr);int key = left;swap(&arr[left], &arr[GetMid(arr, left, right)]);int midi = left + 1;int small = left;int greater = right + 1;while (midi < greater){if (arr[midi] < arr[key]) //将arr[midi]交换到[left + 1, small]区间中,同时注意small位置的元素一定比key元素小{++small;if (small != midi){swap(&arr[small], &arr[midi]);}++midi;}else if (arr[midi] > arr[key]) //将arr[midi]交换到[greater,right]区间{--greater;swap(&arr[midi], &arr[greater]);}else{++midi; //将等于key元素的arr[midi]"括入"[small+1,midi)区间中}}//small指向的元素一定小于keyswap(&arr[small], &arr[key]); //将key交换到其应该出现的最终位置QuickSort(arr, left, small - 1); //分治左子数组QuickSort(arr, midi,right); //分治右子数组 }🤔经过三数取中和三指针优化后的快排就可以对任意序列进行高效排序,不会再出现时间复杂度升阶为O(N^2)的情况
🤔力扣排序测试:(该测试非常针对未经优化和非三指针的快排)
912. 排序数组 - 力扣(Leetcode)
https://leetcode.cn/problems/sort-an-array/description/
🤔与C标准库里的快排进行对比测试:
int main() {srand((unsigned int)time(0));const int N = 10000000;int* arr1 = (int*)malloc(sizeof(int) * N);int* arr2 = (int*)malloc(sizeof(int) * N);int* arr3 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){arr1[i] = rand();arr2[i] = arr1[i];arr3[i] = arr1[i];}int begin2 = clock();qsort(arr2, N, sizeof(int), cmp);int end2 = clock();printf("qsort:%d\n", end2 - begin2);int begin3 = clock();QuickSort(arr3, 0,N-1);int end3 = clock();printf("QuickSort:%d\n", end3 - begin3);free(arr1);free(arr2);free(arr3); }
- 🤔有点奇怪的是在我的机器环境中,我自己写的快排比标准库里的快排还要快一倍左右(可执行程序为release版本)
三.快排时间复杂度再分析
- 😍设N为待排序序列的元素个数
- 😍以下分析中的log都表示以2为底的对数
- 😍经过三数取中和三指针优化后的快排分治递归的递归树可以认为在处理任何序列时都接近一颗满二叉树:(注意数组的分割点不参与后续的单趟排序)
- 😍从递归树的第一层开始,递归树每一层中所有单趟排序所需遍历元素的总个数依次为:N+(N-1)+(N-3)+(N-7)......即快排的时间复杂度计算公式为:
- 😍将上述复杂度公式进行求和运算,取b = logN可得:
- 😍再化简可得:
- 😍可见快速排序的时间复杂度在O(NlogN)的基础上存在进一步的微收敛,这使得快速排序在四个时间复杂度数量级为O(NlogN)的排序算法中独占鳌头进而成为工业级排序中用的最多的排序算法。(四个时间复杂度为O(NlogN)数量级的排序算法分别为:希尔排序,堆排序,归并排序和快速排序)

相关文章:
三路快排(基于三指针单趟排序的快速排序)+快排时间复杂度再分析
目录 一.前言 二. 三路快排 😍算法思想: 😍算法实现步骤: 😍三指针单趟排序的实现: 😍非递归快排完全体: 🤔与C标准库里的快排进行对比测试: 三.快排时间复杂度再分析 一.前言 http://t.csdn.cn/mz8dghttp://…...
Eyeshot Ultimate 2023 Crack
Eyeshot Ultimate 2023 Crack 已经引入了文档类。 工作区。文档现在包含绘制场景内容所需的所有数据。 2022版GEntities已被删除。 最后,一个真正的跨平台中立核心产品是可用的。 新功能 曲线、平面、曲面和体积网格。 屏幕空间环境光遮挡。 托管ReadDWG和ReadDXF类…...
JAVA-8-[SpringBoot]入门程序案例和原理分析
Spring Boot框架入门教程(快速学习版) Spring Boot教程BooTWiki.COM 1 Spring Boot Spring Boot是Pivotal(关键性的)团队在Spring的基础上提供的一套全新的开源框架,其目的是为了简化Spring应用的搭建和开发过程。Spring Boot去除了大量的X…...
前端工程化
一、AST (抽象语法树,Abstract Syntax Tree) 手把手带你走进Babel的编译世界 - 掘金 (juejin.cn) 1、概念 我们所写的代码转换为机器能识别的一种树形结构,本身是由一堆节点(Node)组成,每个节…...
【redis】单线程 VS 多线程(入门)
【redis】单线程 VS 多线程(入门) 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成&#…...
2023蓝桥杯Java研究生组赛题
蓝桥杯Java研究生组、JavaA组看过来,这两个组别题目基本一样 第一次参加了Java研究生组,Java组应该没有C/C那么卷吧,主要是觉得Java组可以避开很多ACM大佬,前面几题感觉难度还行没有特别难,后面几个大题依旧是没法做&a…...
多维时序 | MATLAB实现CNN-BiLSTM-Attention多变量时间序列预测
多维时序 | MATLAB实现CNN-BiLSTM-Attention多变量时间序列预测 目录多维时序 | MATLAB实现CNN-BiLSTM-Attention多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 MATLAB实现CNN-BiLSTM-Attention多变量时间序列预测,CNN-BiLSTM-Atte…...
微积分——Rolle定理的理解(罗尔定理)
极值定理(Extreme Value Theorem)指出,闭区间[a,b]上连续的函数既有最大值,也有最小值。然而,其最大最小值都可能发生在端点。罗尔定理(Rolle’s Theorem)以法国数学家Michel Rolle(1652-1719)的名字命名,它给出了极值存在于闭区间…...
linux内核之select/poll/epoll
一些主流应用IO多路复用技术,突破高并发问题,如nginx、redis、netty,分布式服务框架dubbo,大数据组件hadoop、spark、flink、hbase纷纷使用netty作为网络通信组件。 一、背景:C10K问题 The C10K problem 最早被Dan …...
文件流下载
文件下载 后端传给前端json数据流,前端拿到之后存放在自定义的文件中import axios from "axios"; import qs from "query-string"; import {Notification } from "@arco-design/web-vue"; // 接口中需要含有文件名fileName export function dow…...
C语言模拟实现:atoi函数
在实现atoi之前我们先来了解一下atoi函数的作用是什么: 目录 1.实例演示 2.模拟实现 2.1 判断是否为空指针 2.2判断是否为空字符串 2.3判断正负号 2.4判断非数字字符 2.5判断是否越界 2.6完整代码 1.实例演示 //实例演示 #include <stdio.h> #include …...
LeetCode.每日一题 2427. 公因子的数目
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
蓝牙BQB认证 - HFP profile配置说明
零.声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。 第二篇:Trans…...
【接口测试工具】Eolink Apikit 快速入门教程
Eolink Apikit 下载安装【官方版】:https://www.eolink.com/apikit 发起 API 测试 进入 API 文档详情页,点击上方 测试 标签,进入 API 测试页,系统会根据 API 文档自动生成测试界面并且填充测试数据。 填写请求参数 首先填写好请…...
使用Python和OpenCV实现实时人脸检测并保存截图
在本篇博客中,我们将使用Python和OpenCV库实现一个实时人脸检测的小项目。我们将利用OpenCV中的Haar级联分类器来检测摄像头捕获的图像中的人脸。 项目功能 通过摄像头实时捕获视频流。使用Haar级联分类器检测视频帧中的人脸。在检测到的人脸周围绘制矩形框。实时…...
[linux kernel]slub内存管理分析(7) MEMCG的影响与绕过
文章目录背景前情回顾描述方法约定MEMCG总览省流总结简介slub 相关 memcg机制kernel 5.9 版本之前结构体初始化具体实现kernel 5.9-5.14kernel 5.14 之后突破slab限制方法cross cache attackpage 堆风水总结背景 前情回顾 关于slab几个结构体的关系和初始化和内存分配和释放的…...
MySQL创建数据库(CREATE DATABASE语句)
在 MySQL 中,可以使用 CREATE DATABASE 语句创建数据库,语法格式如下: CREATE DATABASE [IF NOT EXISTS] <数据库名> [[DEFAULT] CHARACTER SET <字符集名>] [[DEFAULT] COLLATE <校对规则名>]; [ ]中的内容是可选的。语…...
【JavaWeb】4—Tomcat
⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~😊 如果文章对你有所帮助,可以点赞👍…...
宝塔Linux面板部署Python flask项目
目录 👉1、前言 👉2、安装python项目管理器 👉3、上传项目文件及文件夹 👉4、配置项目 👉5、请求测试 学习记录: 👉1、前言 写在前面:前几天我们实现了外网内外登录正方教务系…...
spring中产生bean的几种方式
BeanImportMyImportSelector implements ImportSelectorMyImportBeanDefinitionRegistarimplements ImportBeanDefinitionRegistrarFactoryBean这里着重讲解FactoryBean如何判断当前bean是否是FactoryBeanorg.springframework.beans.factory.support.AbstractBeanFactory#isFac…...
AI超级计算机架构演进与性能优化解析
1. AI超级计算机的技术架构演进AI超级计算机的核心架构在过去六年发生了显著变化。2019年主流系统如Summit主要采用NVIDIA V100 GPU,而到2025年,xAI的Colossus已升级到H100/H200混合架构。这种演进主要体现在三个维度:1.1 计算单元设计原理现…...
硬件入门 + 单片机基础(第14天)综合通信实训
ESP32 物联网结业项目:WiFi MQTT 继电器 温湿度 整合完整版 项目说明 这是物联网综合结业项目,整合了你学过的所有核心技术: WiFi 自动联网 断网重连MQTT 远程控制继电器(开关)DHT11 温湿度自动上报心跳包 消息…...
基于LabVIEW与麦克风阵列的实时噪声源定位系统设计与实践
1. 项目概述:从“听见”到“看见”噪声在工业现场、产品研发或环境监测中,我们常常遇到一个棘手的问题:噪声到底是从哪里来的?传统的单点声压级测量只能告诉我们“这里有多吵”,却无法回答“是谁在吵”以及“它在哪里吵…...
Claude Code安装+配置国产大模型+CC Switch
Claude Code 是一个运行在终端(Terminal)里的 AI 程序员。 它不仅仅是一个聊天框,它拥有操作你电脑文件的权限 https://code.claude.com/docs/en/setup 安装 前提条件 需要 Node.js 18 或更新版本 macOS 用户推荐使用 nvm 或 Homebrew 安装…...
别再为‘No module named matlab.engine’抓狂了!手把手教你MATLAB与Python版本匹配与绑定(附Anaconda虚拟环境指南)
彻底解决MATLAB与Python版本冲突:从原理到实战的完整指南 当你兴奋地想在Python中调用MATLAB强大的信号处理功能时,突然跳出的"No module named matlab.engine"错误提示就像一盆冷水浇下来。这不是简单的安装问题,而是两个生态系统…...
HunterPie完全指南:如何在《怪物猎人世界》中获得实时数据监控优势
HunterPie完全指南:如何在《怪物猎人世界》中获得实时数据监控优势 【免费下载链接】HunterPie-legacy A complete, modern and clean overlay with Discord Rich Presence integration for Monster Hunter: World. 项目地址: https://gitcode.com/gh_mirrors/hu/…...
暑期旅游网络诈骗演化与 AI 赋能防御体系研究
摘要 2026 年暑期旅游旺季到来,在线预订、短信通知、证件办理等全流程成为网络诈骗高发场景。The420.in 于 2026 年 5 月 16 日发布的安全预警显示,虚假通行费钓鱼短信、AI 伪造房源预订、虚假政务证件网站、深度伪造语音与视频四类诈骗呈产业化、规模化…...
38岁大厂P9被裁后卖保险:成年人的职场,没有铁饭碗
来自:推荐一个程序员编程资料站:http://cxyroad.com副业赚钱专栏:https://xbt100.top2024年IDEA最新激活方法后台回复:激活码CSDN免登录复制代码插件下载:CSDN复制插件以下是正文。01 | P9也不是免死金牌最近在网上看到…...
求职自动化工具箱:用爬虫与状态机构建高效求职管理系统
1. 项目概述:一个求职者的工具箱如果你正在找工作,或者未来某天需要找工作,你大概率会和我有一样的感受:整个过程繁琐、重复,且充满不确定性。从海投简历到追踪进度,从准备面试到复盘总结,每个环…...
MTKClient终极指南:5步掌握联发科芯片调试的核心技能
MTKClient终极指南:5步掌握联发科芯片调试的核心技能 【免费下载链接】mtkclient MTK reverse engineering and flash tool 项目地址: https://gitcode.com/gh_mirrors/mt/mtkclient 你是否曾经遇到过联发科设备刷机失败、系统崩溃无法恢复的困境?…...














