【C/C++ 05】快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序算法,其基本思想是:任取待排序序列中的某元素作为基准值,按照该基准值将待排序集合分割成两个子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后左右子序列递归该过程,直到所有元素都排列在相应的位置上为止。

  • 排序对象:数组、链表
  • 时间复杂度:O(n * \log n)
  • 空间复杂度:O(1)
  • 是否稳定:否
// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int array[], int left, int right)
{if(right - left <= 1)return;// 按照基准值对array数组的 [left, right)区间中的元素进行划分int div = partion(array, left, right);// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)// 递归排[left, div)QuickSort(array, left, div);// 递归排[div+1, right)QuickSort(array, div+1, right);
}

上述为快速排序算法递归实现的主框架,与二叉树前序遍历的规则类似。

快速排序算法可以由多种实现方法,如霍尔法、挖坑法、前后指针法,目前最优的算法是前后指针法,其基本思路是:

  1. 选择数组中的一个元素作为枢轴(一般是第一个元素),其元素为关键值key,而key值最好是数组的中位数(仅在前中后三个元素中取中位数)
  2. 将数组划分为两个子数组,左子数组的元素都小于等于枢轴元素,右子数组的元素都大于等于枢轴元素
  3. 对这两个子数组分别递归调用快速排序算法,继续进行划分和排序
  4. 递归的结束条件是子数组的长度为1或0,即已经有序或为空数组,不需要再进行排序
  5. 通过不断划分和排序,最终实现整体的排序
  6. 在划分过程中,通过比价元素与枢轴元素的大小关系,将元素划分到对应的区域

// 数组开始、中间、结尾三个元素找到中位数,将其作为key值并返回下标
int MidIndex(int* arr, int l, int m, int r)
{if (arr[l] < arr[r]){if (arr[m] < arr[l])return l;else if (arr[m] > arr[r])return r;elsereturn m;}else{if (arr[m] > arr[l])return l;else if (arr[m] < arr[r])return r;elsereturn m;}
}// 前后指针法(快慢指针法)
// 快排每一次递归的核心就是PtrPtr算法返回新的关键字key的下标
// 每一次PtrPtr算法就是为了将小于key的数移到key的左边,将大于key的数移到key的右边
// 当多次进行递归后,数组的有序度已经很高了,所以此时也可以不再递归而是采用直接插入排序
int PtrPtr(int* arr, int begin, int end)
{if (begin >= end)return;int slow = begin;int fast = slow + 1;while (fast <= end){if (arr[fast] < arr[begin] && ++slow != fast)Swap(&arr[slow], &arr[fast]);fast++;}Swap(&arr[begin], &arr[slow]);return slow;	// 返回新的key值下标
}void QuickSort(int* arr, int begin, int end)
{if (begin >= end)return;int mid = (begin + end) / 2;int iKey = MidIndex(arr, begin, mid, end);Swap(&arr[begin], &arr[iKey]);iKey = PtrPtr(arr, begin, end);QuickSort(arr, begin, iKey - 1);QuickSort(arr, iKey + 1, end);
}

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

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

相关文章

数据在网络传输中为什么要加密?

在信息化浪潮席卷全球的今天&#xff0c;数据如同流淌在信息高速公路的生命血液&#xff0c;其安全传输的重要性不言而喻。随着网络空间中各种威胁与挑战日益凸显&#xff0c;加密技术已成为保护数据安全、维护用户隐私、确保业务连续性的关键手段。它就如同一道无形的防护盾&a…

Nestjs 全局拦截器

一、拦截器 拦截器作用&#xff1a; 在函数执行之前、之后绑定额外的逻辑转换函数的返回结果转换从函数抛出的异常扩展基本函数的行为根据所选条件重写函数 期望接口返回一个标准的json格式&#xff0c;利用拦截器对数据做全局的格式化 {code: "200",data: [],mess…

【文本到上下文 #7】探索 NLP 中的 Seq2Seq、编码器-解码器和注意力机制

一、说明 今天&#xff0c;我们将探讨序列到序列 &#xff08;seq2seq&#xff09; 模型的复杂工作原理&#xff0c;特别关注编码器-解码器架构和注意力机制。这些概念是各种 NLP 应用的基础&#xff0c;从机器翻译到问答系统。 这是可以期待的&#xff1a; Seq2Seq模型中的编码…

数据结构之单链表详解

前言 之前大摆了5天多&#xff0c;没怎么学编程&#xff0c;自昨日起&#xff0c;觉不可如此&#xff0c;痛定思痛&#xff0c;开始继续学习&#xff0c;昨天刷了20多道简单级别的力扣&#xff0c;今天想把链表好好巩固一下&#xff0c;于是乎&#xff0c;把单链表的增删查改搞…

基础算法之Huffman编码

// Type your code here, or load an example. #include<iostream> #include<string> #include<queue> #include <unordered_map> #include <vector>using namespace std;//树节点结构 struct Node {char ch;int freq;Node *left;Node *right;No…

数据结构3、基于栈的后缀算术表达式求值

1 题目描述 图1 中缀表达式转化为后缀表达式题目描述 图2 基于栈的后缀算术表达式求值题目描述 2 题目解读 借助一个运算符栈&#xff0c;可将中缀表达式转化为后缀表达式&#xff1b;借助一个运算数栈&#xff0c;可对后缀表达式求值。借助一个运算符栈和一个运算数栈&#xf…

Java基础数据结构之哈希表

概念 顺序结构以及平衡树 中&#xff0c;元素关键码与其存储位置之间没有对应的关系&#xff0c;因此在 查找一个元素时&#xff0c;必须要经过关键 码的多次比较 。 顺序查找时间复杂度为 O(N) &#xff0c;平衡树中为树的高度&#xff0c;即 O( log2N ) &#xff0c;搜索的效…

防火墙用户认证、NAT、策略路由、DNS透明代理以及双机热备笔记

用户认证 防火墙管理员登录认证 --- 检验身份的合法性&#xff0c;划分身份权限 用户认证 --- 上网行为管理的一部分 用户&#xff0c;行为&#xff0c;流量 --- 上网行为管理三要素 用户认证的分类 上网用户认证 --- 三层认证 --- 所有的跨网段的通信都可以属于上网行为。…

【Web前端实操19】商城官网_分析与顶部广告

本次实操主要是借用小米之前的网站来进行参考&#xff0c;达成网站静态页面开发的目的&#xff0c;而新学者想要一次性直接开发整个网站&#xff0c;肯定会很懵圈&#xff0c;因此&#xff0c;这个商城官网我会一部分一部分地进行拆分来写&#xff0c;最后合成整个界面。 本次…

国企重组整合后,如何严把“选人用人”关?

三年国企改革之后&#xff0c;新一轮国企改革明确重组方向&#xff0c;强调将“战略性重组和专业化整合”作为深化供给侧结构性改革从而建设世界一流企业的重要抓手&#xff0c;推动了国有资源的高效运转流动。在很多企业兼并、重组后&#xff0c;成立了新的集团性公司&#xf…

Mysql查询数据

1 基本查询语句 MySQL从数据表中查询数据的基本语句为SELECT语句。SELECT语句的基本格式是&#xff1a; 2 单表查询 2.1 查询所有字段 SELECT * FROM 表名; 2.2 在SELECT语句中指定所有字段 SELECT f_id, s_id ,f_name, f_price FROM fruits; 2.3 查询单个字段 SELECT 列名FR…

nginx部署前端(vue)项目及配置修改

目录 一、前端应用打包 二、部署前端应用 1、上传前端文件夹 2、修改nginx配置文件 3、重启nginx 三、查看效果 nginx安装参考&#xff1a;linux安装nginx-CSDN博客 一、前端应用打包 打包命令 npm run build 打包成功如下&#xff0c;会在项目路径下生成dist文件夹 二…

Windows Server 2003 Web服务器搭建

系列文章目录 目录 系列文章目录 前言 一、Web服务器是什么&#xff1f; 二、配置服务器 1.实验环境搭建 2.服务器搭建 1)控制面板中找到增加或删除程序打开 2)点击增加程序 3)安装Web服务器 4)查看安装是否成功 5)打开Internet信息服务(IIS)管理器,进行配置 6)找…

【开源之美】:cppcheck

一、项目链接 https://github.com/danmar/cppcheck/tree/main 二、效果示例

图像复原的天花板在哪里?SUPIR:开创性结合文本引导先验和模型规模扩大

SUPIR&#xff08;Scaling-UP Image Restoration&#xff09;&#xff0c;这是一种开创性的图像复原方法&#xff0c;利用生成先验和模型扩大规模的力量。通过利用多模态技术和先进的生成先验&#xff0c;SUPIR在智能和逼真的图像复原方面取得了重大进展。作为SUPIR中的关键催化…

如何配置MacLinuxWindows环境变量

这里写目录标题 什么是环境变量什么是PATH为什么要配置环境变量 如何配置环境变量环境变量有哪些环境变量加载顺序环境变量加载详解 配置参考方法一&#xff1a; export PATHLinux环境变量配置方法二&#xff1a;vim ~/.bashrcLinux环境变量配置方法三&#xff1a;vim ~/.bash_…

go语言基础之泛型

1.泛型 泛型是一种独立于所使用的特定类型的编写代码的方法。使用泛型可以编写出适用于一组类型中的任何一种的函数和类型。 1.1 为什么需要泛型 func reverse(s []int) []int {l : len(s)r : make([]int, l)for i, e : range s {r[l-i-1] e}return r }fmt.Println(reverse…

红外热成像仪定制_热成像仪/红外夜视仪开发方案

红外热成像技术是一种利用红外热成像仪将物体发出的不可见红外辐射能量转换成可见的温度场图像的技术&#xff0c;通过不同颜色来表示不同温度。这项技术的应用领域非常广泛&#xff0c;从电路维修到暖通检测再到汽车故障排查等各个领域都有着重要的作用。 红外热成像仪的解决方…

SpringBoot项目实现热部署的配置方法

SpringBoot项目实现热部署的配置方法 1、什么是热部署&#xff1f; 热部署&#xff0c;就是在应用正在运行的时候升级软件&#xff0c;却不需要重新启动应用。 2、什么是SpringBoot热部署&#xff1f; SpringBoot热部署就是在项目正在运行的时候修改代码, 却不需要重新启动…

PCB的通孔,盲孔,埋孔

通孔&#xff1a;双层板从顶层到底层的打通&#xff0c;这样电流就能够从顶层到底层 盲孔&#xff1a;因为看不到底&#xff0c;像一口井一样&#xff0c;只能打到中间&#xff0c;里面灌上铜&#xff0c;我们可以从第一层切换到第二层&#xff0c;第三层等等&#xff0c;盲孔…