【算法基础】快速排序

news2024/9/21 14:42:13

目录

一、快速排序核心思想

二、快速排序步骤

                (1)暴力做法

                (2)双指针做法

三、代码模板

四、边界问题

五、总结


一、快速排序核心思想

分治,即将一个序列划分成左部分小于等于x,右部分大于等于x

二、快速排序步骤

 

确定一个分界点x。分界点可以是左端 a[l]、右端a[r]、中间值a[(l+r) / 2]、以及随机取值。

调整区间。将数组一分为二,使≤x在左边,≥x在右边。【重点】

递归处理左右两个部分。

 Q:如何将数组一分为二,使≤x在左边,≥x在右边呢?

(1)、暴力做法:

1> 开辟两个数组从c[ ]、b[ ]。

2>将原数组a[ ]中把≤x的元素放在c[ ]中,≥x放在b[ ]中。

3>最后将c[ ] 放入 a[ ],c[ ]放入a[ ]。

(2)、双指针做法(推荐)

 

首先先让指针 i++ 向中间寻找元素,直到指向的元素 ≥x 停下

同样地,再将指针 j - -向中间寻找元素,直到指向的元素 ≤x 停下

当条件满足 i < j,就将这两个元素交换

最终指针 j 就一定会在指针 i 的前面 


举个例子,如下图所示

三、代码模板

void quick_sort(int a[],int l,int r)
{
    if(l >= r) return; //如果数组中就一个数,就已经排好了(递归出口) 
    int x = a[(l + r) / 2]; //确定分界点
    int i = l - 1,j = r + 1;
    while (i < j)
    {
        do i++; while(a[i] < x);
        do j--; while(a[j] > x);
        if (i < j) swap(a[i],a[j]);
    }
    //递归处理左部分
    quick_sort(a,l,j);
    //递归处理右部分
    quick_sort(a,j + 1,r);
}

四、边界问题

①为什么要使用 do while循环而while循环

while(a[i] < x) i++;
while(a[i] > x) j--;

如图所示,假设数组中有相同的元素,会死循环

 

②为什么移动移动 i 和 j的条件分别是 < x 和 > x,而不是一开始所说的 <= x 和 >= x

如果分界点x,恰好是数组中最大值,会导致 i++ 越界。

同理,如果分界点又恰好是数组中最小值,也会导致 j -- 越界。

 ③当x=a[l]

递归部分就不能使用quick_sort(a,l,i - 1)、quick_sort(a,i,r)

假设数组只有1和2在排序时,假设分界点x = 1,因此 到时候 i 和 j 会同时指向1,对于第一个递归quick_sort(a,0,- 1),相当于没有值,也就没有交换,但到了第二个递归quick_sort(a,0,2),就一直就这两个数交换,导致了死递归

④当x = a[r]

递归部分就不能使用quick_sort(a,l,j)、quick_sort(a,j + 1,r)

例子和①一样

⑤当x=a[(l + r) /2]

同样的道理,假设数组中只有2个元素分别是1和2,这时,分界点x = 1,这种情况和③类似,就不能使用quick_sort(a,l,i - 1)、quick_sort(a,i,r)

⑥当x=a[(l + r + 1) / 2]

递归部分就不能使用quick_sort(a,l,j)、quick_sort(a,j + 1,r)

 五、总结


(1)当x=a[l] 或者 x=a[(l + r) /2],只能用

quick_sort(a, l, j); //左半部分递归
quick_sort(a,j + 1, r); //右半部分递归

(2)当x=q[r] or x=q[l+r + 1>>1],只能用

quick_sort(a,l,i - 1);//左半部分递归
quick_sort(a, i, r);//右半部分递归

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

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

相关文章

【Linux】两个故事带你使用git命令行

目录一.历史故事背景经过git的诞生二.git版本管理1.小故事2.理解版本管理三.git的使用1.仓库的创建2.安装git和仓库克隆3.上传代码三板斧addcommitpushgithub和gitee是代码的托管平台&#xff0c;我们上传代码或文件在其中&#xff0c;来管理我们的代码和不同版本软件。 在多人…

【操作系统】——主流的操作系统(带你快速了解)

&#x1f4dc; “作者 久绊A” 专注记录自己所整理的Java、web、sql等&#xff0c;IT技术干货、学习经验、面试资料、刷题记录&#xff0c;以及遇到的问题和解决方案&#xff0c;记录自己成长的点滴。 &#x1f341; 操作系统【带你快速了解】对于电脑来说&#xff0c;如果说…

【Java IO流】字符集使用详解

文章目录前言ASCIIGBKUnicode为什么会出现乱码前言 上一节关于字节流的文章中&#xff0c;在使用字节流读取本地文件中的数据时&#xff0c;文件中只存放了英文&#xff0c;而并没有存放中文数据。我们还提到了不建议使用字节流读取纯文本文件的数据&#xff0c;否则会出现乱码…

Elasticsearch7.8.0版本高级查询—— 匹配查询文档

目录一、初始化文档数据二、匹配查询文档示例2.1、概述2.2、示例一、初始化文档数据 在 Postman 中&#xff0c;向 ES 服务器发 POST 请求 &#xff1a;http://localhost:9200/user/_doc/1&#xff0c;请求体内容为&#xff1a; {"name":"张三","age&…

浅谈php原生类的利用 2(ErrorSoapClientSimpleXMLElement)

除了上篇文章浅谈 php原生类的利用 1(文件操作类)_php spl原生类_葫芦娃42的博客-CSDN博客 里提到的原生利用文件操作类读文件的功能&#xff0c;在CTF题目中&#xff0c;还可以利用php原生类来进行XSS,反序列化&#xff0c;SSRF&#xff0c;XXE。 常用内置类&#xff1a; Dire…

【SAP Abap】X档案:SAP Native SQL 简介及实现方式(EXEC SQL、ADBC、AMDP)

SAP Native SQL 简介及实现方式&#xff08;EXEC SQL、ADBC、AMDP&#xff09;1、SAP Open SQL 与 Native SQL 的特点2、Native SQL 的实现方式方式一&#xff1a;Exec SQL&#xff08;1&#xff09;获取单值&#xff08;2&#xff09;获取多行&#xff08;3&#xff09;游标应…

TCP协议的长连接和短连接详解

一 前言TCP在真正开始进行数据传输之前&#xff0c;Server 和 Client 之间必须建立一个连接。当数据传输完成后&#xff0c;双方不再需要这个连接时&#xff0c;就可以释放这个连接。TCP连接的建立是通过三次握手&#xff0c;而连接的释放是通过四次挥手。所以说&#xff0c;每…

【SpringCloud】Eureka的基本原理与使用

【SpringCloud】Eureka的基本原理与使用 一、Eureka-提供者与消费者 【问】如果服务A调用了服务B&#xff0c;而服务B又调用了服务C&#xff0c;服务B的角色是什么&#xff1f; 二、Eureka的结构和作用 什么是Eureka&#xff1f; Eureka 解决服务调用的问题 order-servic…

博物馆3d数字化全景展示设计方案

作为近几年新兴的营销方式&#xff0c;交互式营销能够让消费者对产品从主动感兴趣到互动体验&#xff0c;甚至自主自发传播&#xff0c;达到“在销售中传播&#xff0c;在传播中销售”的目的。进入数字体验经济时代&#xff0c;当3d数字化展示技术遇上传统行业&#xff0c;3d数…

Redis原理篇(三)通信协议

一、RESP协议 1、定义 Redis是一个cs架构的软件&#xff0c;通信一般分两步&#xff1a; 客户端client向服务端server发送一条命令服务端解析并执行命令&#xff0c;返回响应结果给客户端 因此客户端发送命令的格式、服务端响应结果的格式必须有一个规范&#xff0c;这个规…

HashMap源码学习:JDK1.8版本源码解析

文章导航 HashMap源码学习&#xff1a;红黑树原理详解 HashMap源码学习&#xff1a;JDK1.8版本源码解析 目录文章导航前言正文HashMap重要属性HashMap构造方法HashMap扩容方法HashMap链表迁移HashMap红黑树迁移HashMap链表转红黑树HashMap红黑树转链表HashMap添加数据HashMap移…

让你彻底明白Java SPI与SpringBoot自动配置,内附实例代码演示

一、Java SPI的概念和术语 SPI&#xff1a;全称是Service Provider Interface&#xff1a;是一种基于ClassLoader来发现并加载服务的机制 SPI由三个组件构成&#xff1a;Service、Service Provider、ServiceLoader Service&#xff1a;是一个公开的接口或抽象类&#xff0c;定…

数说菊风2022

春风传捷报&#xff0c; 梅韵贺新年&#xff01; 2022&#xff0c;已悄然划过&#xff0c; 就让我们用数字说话&#xff0c; 述说这年的精彩&#xff01; 树十大标杆案例 国际运营商战略合作——Telkomsel 携手印尼运营商Telkomsel在RCS融合通信和RTC实时音视频领域形成合…

golang入门笔记——kitex

WSL的安装 由于Kitex并不支持Linux&#xff0c;所以需要首先安装WSL2 WSL一句话来说就是微软出的一个虚拟机工具 Win11下安装WSL2的步骤为&#xff1a; 1.“开始菜单”搜索功能&#xff0c;打开“启动或关闭Window功能” 2.勾选以下功能 1.适用于Linux的Window子系统 2.虚…

qsort函数

目录1.什么是qsort函数2.实现一个qsort函数3.用qsort函数排序一个结构体4.模仿qsort的功能实现一个通用的冒泡排序1.什么是qsort函数 我们以前学习过的一些排序算法&#xff0c;如冒泡、希尔、快排等等&#xff0c;它们速度有快有满&#xff0c;但是这些排序都只能排序一种类型…

iOS 内存泄漏检测 Instruments Leaks

Xcode 中 按住 command I 或者菜单栏 Product – Profile 2. 双击 Leaks 或者按 choose&#xff0c;打开 Leaks 面板 3. 在显示的 Leaks 面板中&#xff0c;点击左上角红色点&#xff0c;即可运行内存检测。 4. 在运行过程中如果发现Leak Checks&#xff08;如图&#xff09;…

【C进阶】C进阶练习编程题

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C语言进阶 ⭐代码仓库&#xff1a;C Advanced 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们…

关闭“此版本的Windows不再支持Microsoft Edge”提示

在Win7中&#xff0c;安装Microsoft Edge&#xff0c;升级到“109.0.1518.55 (正式版本)”后&#xff0c;打开Edge会弹出提示&#xff1a; 此版本的 Windows 不再支持 Microsoft Edge。升级到 Windows 10 或更高版本&#xff0c;以从 Microsoft Edge 获取常规功能和安全更新。 …

ESPNet: 自动驾驶领域轻量级分割模型

论文标题&#xff1a;ESPNet: Efficient Spatial Pyramid of Dilated Convolutions for Semantic Segmentation 论文地址&#xff1a;https://arxiv.org/pdf/1803.06815v2.pdf 开源地址&#xff1a; https://github.com/sacmehta/ESPNet 论文思想 ESPNet是用于语义分割的轻量…

一文弄懂Linux虚拟机网络配置

文章目录计算机网路基础网络连接模式Bridged&#xff08;桥接模式&#xff09;NAT&#xff08;地址转换模式&#xff09;Host-Only&#xff08;仅主机模式&#xff09;Linux常用网络相关命令ifconfig&#xff1a;配置网络接口ping&#xff1a;测试主机之间网络连通性修改ip地址…