快速排序的改进(超详细!!!)

ops/2024/9/20 1:20:42/ 标签: 算法, java, 数据结构, vim, c++, c语言, 排序算法

改进前的快速排序

代码实现:

//快速排序
void quick(int arr[],int start,int end){int i = start;int j = end;int mid = arr[start];int tmp;while(i < j){//从头往后找,比基准小就继续while(arr[i] < mid){i++;}//循环结束,i的位置大于等于基准元素//从后往前找,比基准大就继续while(arr[j] > mid){j--;}//循环结束,j的位置小于等于基准元素//交换位置tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}if(start < j){quick(arr,start,j-1);}if(end > j){quick(arr,j+1,end);}}
int main(){int num[] = {20,30,20};quick(num,0,2);for(int i = 0; i < 9;i++){printf("%d ",num[i]);}printf("\n");return 0;
}

        

         对于{20,30,20}这样一个有重复数字的队列,基准元素与下标i和下标j的元素相等时就会陷入死循环,当他们交换位置后,arr[i] < mid 不成立,跳出循环。arr[j] > mid 不成立,跳出循环。继续发生交换位置。再次比较外层循环 i  <  j 成立,继续内层循环。程序就会一直卡在这里。

改进后的快速排序

代码实现:

void quick(int arr[], int start, int end) {if (start >= end) {//1.start>end,子数组没有元素//2.start=end,子数组只有一个元素return; // 递归终止条件}int i = start;int j = end;int pivot = arr[start]; // 选择第一个元素作为基准while (i < j) {// 从右向左找小于基准的元素while (i < j && arr[j] >= pivot) {j--;}// 从左向右找大于基准的元素while (i < j && arr[i] <= pivot) {i++;}// 交换i和j位置的元素if (i < j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}}//当 i = j时,arr[i]一定是小于等于基准的值// 最后将基准放到正确的位置arr[start] = arr[i];arr[i] = pivot;// 递归处理基准左右两边的数组quick(arr, start, i - 1);quick(arr, i + 1, end);
}int main() {int num[] = { 20,30,20};int size = sizeof(num) / sizeof(num[0]);quick(num, 0, size - 1);for (int i = 0; i < size; i++) {printf("%d ", num[i]);}printf("\n");return 0;
}

        我们先从右向左开始找小于基准的元素(注意一定是先从右向左,后从左向右寻找),在从左向右找大于基准的元素,同时在寻找过程中一直保持 i < j,二者有一个不满足就跳出当前循环。

        为什么先从右向左再从左向右找,反过来不可以吗?

        不可以,我们先从右向左找小于基准的元素,再从左向右找大于基准的元素,如果(i  <  j )之后交换此时(i 和 j)位置上的元素,之后在进入循环判断。这样当(i  ==  j)时,arr[i] 一定是小于等于 基准元素。因为交换位置前 arr[i]  > pivot, arr[j] < pivot, 交换位置后arr[i] < pivot,     arr[j] > pivot,此时j先向左移动,i再根据(i 和 j)大小关系再判断是否往右移动,(因为是j先移动,所以j停下来一定是遇到比基准元素小的元素 或者 i==j 这样的情况)这样我们能够确保(i == j)时 ,arr[i] 一定是小于等于基准元素。

//当 i = j时,arr[i]一定是小于等于基准的值// 最后将基准放到正确的位置arr[start] = arr[i];arr[i] = pivot;

        此时因为arr[i] 是小于或者等于基准元素的,我们让arr[i]往左放,pivot放在arr[i] 的位置上,这样我们就能保证基准左边的一定是小于等于基准元素的,右边一定是大于等于基准元素的。

 

        之后就是递归函数的使用了,难点在于理解 

//当 i = j时,arr[i]一定是小于等于基准的值// 最后将基准放到正确的位置arr[start] = arr[i];arr[i] = pivot;

这段代码的作用,交换i==j时的元素与基准元素,另外必须是先从右向左找再从左向右找很重要)还有就是递归函数的终止条件(代码注释已经说的很明白了,不另做赘述)

if (start >= end) {//1.start>end,子数组没有元素//2.start=end,子数组只有一个元素return; // 递归终止条件}


http://www.ppmy.cn/ops/97062.html

相关文章

【企业高性能web服务器】

目录 一、Nginx 介绍1、 Nginx 功能介绍2、基础特性3、Nginx 模块介绍 二、Nginx 编译安装1、编写systemd服务 三、平滑升级和回滚1、平滑升级的流程2、升级2、回滚 四、 Nginx 核心配置详解1、实现 nginx 的高并发配置2、Nginx 账户认证功能3、nginx作为下载服务器配置 五、re…

vue3--定时任务cron表达式组件比较

## 背景&#xff1a; 之前使用vue2开发项目时&#xff0c;使用了cron组件&#xff0c;比较了两种组件的使用效果。现在需要把原有的vue2项目升级为vue3&#xff0c;需要对应的cron组件。 方案一&#xff0c;vue3-cron-plus 具体实现&#xff1a; 安装插件 npm install vue3-…

SEO之网站结构优化(十二-绝对路径和相对路径)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、“新手上云”能够为你开启探索云世界的第一步 博客&#xff1a;阿幸SEO~探索搜索排名之道 绝对路径指的是包含城名的完…

奇异递归Template有啥奇的?

如果一个模版看起来很头痛&#xff0c;那么大概率这种模版是用来炫技&#xff0c;没啥用的&#xff0c;但是CRTP这个模版&#xff0c;虽然看起来头大&#xff0c;但是却经常被端上桌~ 奇异递归模板模式&#xff08;Curiously Recurring Template Pattern, CRTP&#xff09;是一…

数字人的形象克隆与语音克隆是伪需求

形象克隆与语音克隆技术&#xff0c;在当前的环境上已经可以成熟的实现&#xff0c;但真的解决了痛点问题吗&#xff1f; 普通人或者一般的公司克隆自己内部人的形象有必要吗&#xff1f;对外界而言&#xff0c;克隆的形象与虚拟的形象并无二致&#xff0c;本身并没有什么知名…

【区块链+商贸零售】消费券 2.0 应用方案 | FISCO BCOS应用案例

方案基于FISCO BCOS区块链技术与中间件平台WeBASE&#xff0c;实现新一代消费券安全精准高效发放&#xff0c;实现消费激励&#xff0c; 促进消费循环。同时&#xff0c;方案将用户消费数据上链&#xff0c;实现账本记录与管理&#xff0c;同时加密机制保证了数据安全性。

【Axure视频教程】中继器表格——设置文字颜色

今天教大家在Axure制作将控制中继器内部控制文字颜色的原型模板&#xff0c;效果包括&#xff1a; 1、用中继器表格的数据来控制文字的颜色&#xff0c;例如60分以下红色文字&#xff0c;90分以上绿色文字双击分值的格子2 2、可以填写或修改分值&#xff0c;修改后根据新值自…

当SOA遇到DDD

本文讨论软件设计中的决策&#xff0c;特别是关于将较大的系统拆分为多个可独立部署的服务端点。不会特别讨论【服务端点设计】&#xff0c;但我想探讨一下为创建多个服务应用程序进行构思的阶段。 面对复杂问题&#xff0c;通常试图理解复杂性的各部分。将问题拆解为更易于理…

C#使用Modbus TCP通讯PLC,实现读写寄存器

一、创建一个Moudbus类&#xff0c;引入NModbus和Modbus这两个包 #region ModbusTCPpublic class NmodbusTcpHelper{// 静态成员变量&#xff0c;用于存储TcpClient实例private static TcpClient tcpClient null;// 静态成员变量&#xff0c;用于存储ModbusIpMaster实例privat…

一个手机到手机之间通话经过了哪些设备

来源&#xff1a;https://www.bilibili.com/video/BV1ic411F7mM/?spm_id_from333.880.my_history.page.click&vd_source6c5d3cd50fc7fa8732bdfb760a055839 一个手机通话需要经过下面三个网络 类别接入网&#xff08;Access Network&#xff09;承载网&#xff08;Transp…

C语言面试题(持续更新)

1.static/const C语言的关键字 static 修饰 局部变量时 延长了局部变量的生命周期 直到程序结束 作用域取决于定义它的函数 static 修饰 全局变量时 只允许全局变量在定义它的源文件中使用 其他文件不能对其进行调用 static 修饰 函数是 也只允许函数在定义它的源文件中使用…

软件开发者的首选:最佳Bug测试工具Top 10

本篇文章介绍了以下软件bug测试管理工具&#xff1a;PingCode、Worktile、Test360、禅道、码云Gitee、优云测试、Jira、GitHub、Axosoft、Bugzilla。 在开发过程中&#xff0c;Bug的管理往往是最让人头疼的问题之一。小问题积累起来不仅会拖延项目进度&#xff0c;还可能影响到…

【vue】编辑器段落对应材料同步滚动交互

场景需求 编辑器段落对应显示材料编辑器滚动时&#xff0c;材料同步滚动编辑器段落无数据时&#xff0c;材料不显示 实现方法 编辑器与材料组件左右布局获取编辑器高度&#xff0c;材料高度与编辑器高度一致禁用材料组件的滚动事件获取编辑器段落距离顶部的位置&#xff0c;…

三高 vue

高性能是指系统或应用程序在单位时间内能够处理更多的工作量或请求。 高可用性是指系统或服务能够在面对故障或异常情况时保持持续可用和正常运行的能力。 高扩展性是指系统或应用程序能够在面对不断增长的负载时保持性能和吞吐量的能力。 nginx主备keepalived实现nginx服务的高…

Vue 3 watchEffect教程

Vue 3 watchEffect教程 Vue 3 watchEffect教程简介什么是 watchEffect&#xff1f;watchEffect的基本使用引入 watchEffect使用 watchEffect watchEffect的高级用法响应特定响应式状态执行副作用的清理使用 watchEffect 作为响应式引用 watchEffect与Vue 2的watch选项的区别结语…

架站点云自动拼接

southLidar pro 软件里面的架站点云无目标、无传感器的点云自动拼接算法&#xff0c;该算法的特征是速度快&#xff0c;精度高、稳定性高&#xff0c;大部分的场景都能一键自动拼接成功。速度、稳定性&#xff1a;比RealWorks 12、SCENE 2019等软件都快。精度&#xff1a;高于S…

Dart【06】generator生成器函数

什么是生成器函数 Dart生成器函数 (generator) 可以渐进的返回一个值的序列。 Dart内置了两种生成器函数的支持&#xff1a; 同步生成器(sync*)&#xff1a;返回一个Iterable对象。 异步生成器(async*)&#xff1a;返回一个Stream对象。 同步生成器 使用同步生成器修饰的函…

【drools】8.44 例子ubuntu24.04 运行;IntelliJ 修复java: 错误: 不支持发行版本 5

首先是要有jdk 安装:这里是oracle的,不是openjdk ,【ubuntu24.04】安装oracle javasdk– 官方说可以直接跑 root@k8s-master-pfsrv:/home/zhangbin/perfwork/drools/drools-distribution-8.44.0.Final/examples# ./runExamples.sh Usage: ./runExamples.sh For example: .…

python发邮件

1. SMTP&#xff08;简单邮件传输协议&#xff09;基础 SMTP 协议概述 SMTP&#xff08;Simple Mail Transfer Protocol&#xff0c;简单邮件传输协议&#xff09;是用于在计算机网络上传输电子邮件的标准通信协议。它定义了发送邮件的基本规则和流程&#xff0c;确保邮件从发…

LeetCode238.除自身以外数组的乘积

题目大意 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请不要使用除法&#xff0c;且在 O(n)…