经典排序算法之快速排序|c++代码实现|什么是快速排序|如何代码实现快速排序

引言

排序算法c++实现系列第6弹——快速排序

文章末尾还有本菜已实现的其他排序算法文章的链接。不过,排序算法这个系列还没更完,争取本周末搞完!之后还会有堆排序、桶排序等的代码实现,感兴趣的佳人可以点个赞&收藏,如果我有幸获得佳人们一个关注,感激涕零,呜呜呜呜呜呜呜呜...

算法介绍

快速排序(Quick Sort)是一种常见且高效的排序算法,它和归并排序算法一样,都是基于分治法(Divide and Conquer)的思想。快速排序的核心思想是选择一个基准元素,将数组分成两部分,使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素,然后再对左右两部分分别进行递归排序,最终实现整个数组的排序。

算法步骤

下面是快速排序的主要步骤:

  1. 选择基准元素:从待排序数组中选择一个基准元素。通常选择第一个元素、最后一个元素或者中间元素作为基准元素。在本文中我们选择第一个元素为基准元素。

  2. 分区操作:将数组重新排列,将小于基准元素的所有元素移到基准元素的左边,将大于基准元素的所有元素移到基准元素的右边,基准元素本身则放置在最终的位置上。这个操作称为分区(Partition)操作。

    比如说 有子数组a[p:r],下标从p到r。以a[p]为基准元素将a[p:r]划分成3段a[p:q-1],a[q]和a[q+1:r],使a[p,q-1]中任意一个元素小于等于a[q],而a[q+1:r]中任何一个元素大于等于a[q],下标q在划分过程中确定;

    分区操作的具体过程可以看代码和下方的图片。这里简单描述,令 i 指向序列最左侧数据(不算基准元素),j 指向最右侧数据。

    1. i 自前往后(或者说自左往右)寻找大于基准元素的值,找到后停止查找;

    2. j 自后往前(自右往左)寻找小于基准元素的值,找到后停止

    3. 将 arr[i] 与 arr[j] 交换。

    4. 交换完毕后,重复步骤1、2、3,直到分区操作完成

  3. 递归排序:对分区后的左右两个子数组进行递归排序。对左子数组和右子数组分别重复步骤1和步骤2,直到子数组的大小为1或者0,此时子数组已经有序。接上边的例子,即通过递归调用快速排序算法分别对a[p:q-1]和a[q+1:r]进行排序;

具体举例展示:假设有数组a[] = {4,8,7,1,3,5,6,2} ,以第一个元素a[0]为基准元素,可以得到:a[q]=4; a[p: q-1]=[1,2,3]; a[q+1:r]=[7,5,6,8],下图是具体过程展示(建议拿该图用作代码的辅助理解)

时间复杂度

快速排序的平均时间复杂度为 O(nlogn),最坏情况下的时间复杂度为O(n^2),最好情况下的时间复杂度为O(nlogn)。

最坏的情况出现在序列已按递增或递减顺序排列,即数组已经有序。(条件:每次选序列中第一个元素为基准元素)

最好的情况出现在每次选择的基准元素都能将数组分为两个 n/2 区域再进行递归。

同时快速排序是一种原地排序算法,不需要额外的辅助空间。

代码实现

#include<bits/stdc++.h>
using namespace std;
template<typename T>
int partition(T arr[], int l, int r) {int i = l, j = r + 1;T key = arr[l];// 记忆,边界问题一定要小心while (true) {//i<r 没有=,原因:假如有=,则i=r可进入循环,待下一轮,++i为r+1,可能出现数组越界while (arr[++i] < key && i < r) {}   // 两个while循环中与key比较都不加=,原因见代码下方 while (arr[--j] > key) {}if (i >= j)  break; // 等号 必须有,如果a[j]起初刚好是小于key的,而a[i]一路找过来没找到大于key的,最后停在a[j]处;swap(arr[i], arr[j]);}arr[l] = arr[j];arr[j] = key;return j;
}
template<typename T>
void quick_sort(T arr[], int l, int r) {// 思路是先按大小交换,获得pilot的下标,从而好将问题分解为两部分if (l < r) {int k = partition(arr, l, r);quick_sort(arr, l, k - 1);quick_sort(arr, k + 1, r);}}int main() {int arr[] = {61, 17, 29, 22, 34, 60, 72, 21, 50, 1, 62};int len = (int) sizeof(arr) / sizeof(*arr);quick_sort(arr, 0, len - 1);for (int i = 0; i < len; i++) {cout << arr[i] << " ";}cout << endl;float arrf[] = {17.5, 19.1, 0.6, 1.9, 10.5, 12.4, 3.8, 19.7, 1.5, 25.4, 28.6, 4.4, 23.7, 5.4};int lenf = sizeof(arrf) / sizeof(*arrf);quick_sort(arrf, 0, lenf - 1);for (int i = 0; i < lenf; i++) {cout << arrf[i] << " ";}return 0;
}

 

while循环等号解释

在快速排序的分区操作中,加等号可能导致出现问题的原因是在找到小于等于基准值的元素时,如果加了等号,则可能会导致相等的元素被交换,从而影响排序的稳定性。快速排序是一种不稳定的排序算法,意味着相等元素的相对位置在排序后可能会改变,加上等号可能会导致相等元素的顺序被打乱。

举个例子,假设原始数组为[2, 3, 2, 1],如果在分区操作中加上等号,即将arr[i] <= key改为arr[i] < key,那么在分区操作后,可能会得到[2, 1, 2, 3]这样的结果,相等的元素2的相对位置发生了改变。而如果不加等号,则可能会得到[1, 2, 2, 3]这样的结果,保持了相等元素的相对位置不变。

因此,为了保证快速排序的稳定性,一般会选择不加等号的方式来实现分区操作。

运行结果展示:

其他排序算法实现

经典排序算法之希尔排序|c++代码实现||什么是希尔排序|如何代码实现

经典排序算法之归并排序|递归和迭代法代码均提供|c++代码实现|什么是归并排序|如何代码实现

经典排序算法之希尔排序|c++代码实现||什么是希尔排序|如何代码实现

经典排序算法之插入排序|c++实现|什么是插入排序|如何代码实现-CSDN博客

排序算法之选择排序|c++实现-CSDN博客

经典排序算法之冒泡排序|c++代码实现-CSDN博客

 

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

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

相关文章

Igraph入门指南 4

二、图的创建 图分有向图和无向图&#xff0c;所以图的创建有各自的实现方式。 1、手工创建图&#xff1a; 1-1 通过文本创建&#xff1a;graph_from_literal 通过每项提供两个顶点名&#xff08;或ID号&#xff09;作为一条边的格式&#xff0c;手动创建图&#xff0c;顶点…

【敬伟ps教程】文字处理工具

文章目录 文字工具使用方式文字图层文字工具选项字符面板段落面板文字工具使用方式 文字工具(快捷键T),包含横排和直排两种类型 创建文本两种类型:点式文本、段落文本 创建文字方式 1、在画面上单击,出现文字光标,可输入文字,然后需要在工具栏中点击“√”或者 Ctrl+…

数学建模-动态规划(美赛运用)

动态规划模型的要素是对问题解决的抽象&#xff0c;其可分为&#xff1a; 阶段。指对问题进行解决的自然划分。例如&#xff1a;在最短线路问题中&#xff0c;每进行走一步的决策就是一个阶段。 状态。指一个阶段开始时的自然状况。例如&#xff1a;在最短线路问题中&#xff…

docker 运行异构镜像

概述 关于docker镜像在不同的cpu架构下运行报错的解决办法&#xff0c;作者踩坑验证&#xff0c;在此分享经验 某次工作遇到需要银行内部部署docker镜像&#xff0c;由于行内已经开始走信创的路线&#xff0c;使用鲲鹏系统&#xff0c;arm架构&#xff0c;记过就遇到了standa…

ComfyUI-Flowty-TripoSR

这是一个自定义节点&#xff0c;可让您直接从ComfyUI使用TripoSR。TripoSR 是由 Tripo AI 和 Stability AI 合作开发的最先进的开源模型&#xff0c;用于从单个图像快速前馈 3D 重建。&#xff08;TL;DR 它从图像创建 3d 模型。这篇文章主要介绍了将TripoSR作为ComfyUI节点的配…

华容道问题求解_详细设计(四)之查找算法2_BFS

&#xff08;续上篇&#xff09; 利用BFS查找&#xff0c;会找到最短路径&#xff08;没有权重的图&#xff09;&#xff0c;这个道理比较简单&#xff0c;这是由于寻找路径的方法都是从起点或者接近起点的位置开始的。查找过程如果画出图来&#xff0c;类似于一圈圈的放大&…

Leetcode每日一题】 二维前缀和 - 矩阵区域和(难度⭐⭐)(31)

1. 题目解析 题目链接&#xff1a;1314. 矩阵区域和 题目乍一看很晦涩难懂&#xff0c;又是大于等于又是k的 仔细分析&#xff0c;题目所说的意思就是以[i,j]为中心&#xff0c;求上下左右向外拓展k个单位的矩阵和&#xff0c;放在名为answer的矩阵中&#xff0c;最后返回ans…

Session登陆实践

Session登陆实践 Session登录是一种常见的Web应用程序身份验证和状态管理机制。当用户成功登录到应用程序时&#xff0c;服务器会为其创建一个会话&#xff08;session&#xff09;&#xff0c;并在会话中存储有关用户的信息。这样&#xff0c;用户在与应用程序交互的整个会话…

设计模式 代理模式

代理模式主要使用了 Java 的多态&#xff0c;主要是接口 干活的是被代理类&#xff0c;代理类主要是接活&#xff0c; 你让我干活&#xff0c;好&#xff0c;我交给幕后的类去干&#xff0c;你满意就成&#xff0c;那怎么知道被代理类能不能干呢&#xff1f; 同根就成&#xff…

档案室管理人员有哪些岗位

档案室管理人员的岗位可以分为以下几类&#xff1a; 1. 档案文书管理岗位&#xff1a;负责档案文书的管理、整理、归档和借阅工作&#xff0c;包括档案资料的分类、编目、装订、存储等。 2. 档案数字化管理岗位&#xff1a;负责将纸质档案数字化&#xff0c;进行扫描、转换、存…

mac下终端命令提示补全

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 mac下终端命令提示补全 前言Zsh-autosuggestions原理解析&#xff1a;智能提示的工作方式1. 命令历史分析&#xff1a;2. 智能提示生成&#xff1a;3. 用户交互和选择&#xff1a;4. 配置和个性化&…

Linux基础IO【 详 解 】

文章目录 C语言文件IOC语言文件接口汇总默认打开的三个流 系统文件IOopenclosewriteread 文件描述符fd文件描述符的分配规则重定向重定向的本质dup2 FILEFILE当中的文件描述符FILE当中的缓冲区 理解文件系统初识inode磁盘分区与格式化介绍 软硬链接软链接硬链接软硬链接的区别 …

CorelDRAW Graphics Suite2024专业图形设计软件Windows/Mac最新25.0.0.230版

CorelDRAW Graphics Suite 2024是一款专业的图形设计软件&#xff0c;它集成了CorelDRAW Standard 2024和其他高级图形处理工具&#xff0c;为用户提供了全面的图形设计和编辑解决方案。 该软件拥有强大的矢量编辑功能&#xff0c;用户可以轻松创建和编辑矢量图形&#xff0c;…

UI 易用性测试 以及自动化实现!

GUI 是指图形用户界面&#xff0c;UI 是指用户界面&#xff0c;对于纯软件系统&#xff0c;这两者没有本质的区别&#xff0c;GUI易用性测试与 UI 易用性测试内容一致。但是如果测试的对象是一个产品&#xff0c;这两者则存在区别&#xff0c;对于产品 UI 则不仅仅包括 GUI&…

多线程-线程池原子性并发工具类

1.线程池 1.线程状态 虚拟机中线程的六种状态 新建状态&#xff08;NEW&#xff09; --创建线程 就绪状态&#xff08;RUNNABLE&#xff09; --start方法 阻塞状态&#xff08;BLOCKED&#xff09; --无法获得锁对象 等待状态&#xff08;WAITING&#xff09; …

springboot254小区团购管理

小区团购管理设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装小区团购管理软件来发挥其高效地信…

菜鸟笔记-14Python绘图颜色使用

Python中绘图主要依赖于各种库&#xff0c;其中matplotlib是最常用且功能强大的一个。在matplotlib中&#xff0c;你可以使用各种颜色来表示不同的数据点、线条或填充区域。下面我将详细介绍如何在Python中使用matplotlib来设置绘图颜色&#xff0c;并给出具体的例子。 14.1颜…

Spring循环依赖问题分析

对象分类&#xff1a;1.成品对象&#xff1a;实例化完成 初始化完成 2.半成品对象&#xff1a; 实例化完成 初始化未完成 实例化和初始化可以分开执行是解决循环依赖问题的关键 一级缓存&#xff1a;保存完成的bean对象 二级缓存&#xff1a;存储成品对象 三级缓存&#xff1a…

《北上广深杭》都有哪些最值得加入的互联网大厂

IT行业做技术很公平&#xff0c;没那么看重出身&#xff0c;只要你技术好&#xff0c;能力强&#xff0c;就能进大厂&#xff0c;拿高薪。IT行业算是目前为数不多的比较容易屌丝逆袭的行业之一&#xff0c;IT行业也从来不缺少造富神话。一起加油吧&#xff0c;打工人&#xff0…

Python 创建PPT

本篇为如何使用Python来创建ppt文件。 创建PPT 安装必要的库 命令如下&#xff1a; pip install python-pptx 安装过程&#xff1a; 创建ppt文件 在当前目录下创建一个test的ppt文件。其中包含两页&#xff0c;分别使用了不同的布局。 第一页设置了标题和内容。第二页只设…