非递归实现的快速排序
目录
序列文章
前言
学前补充
非递归快速排序
注意事项(重要)
实现步骤
代码实现
时空复杂度
快速排序的特性
栈的相关代码
序列文章
非递归实现的快速排序:http://t.csdnimg.cn/UEcL6
快速排序的挖坑法与双指针法:http://t.csdnimg.cn/I1L7Q
快速排序的hoare法:http://t.csdnimg.cn/SV0nA
前言
一般来说,我们在写排序时都比较喜欢使用递归的方式,但是递归如果层次太深可能会引起栈溢出的问题,所以我们在本篇会讲解如何使用非递归的方式实现快速排序\( ̄︶ ̄*\))
学前补充
对于递归改非递归我们其实已经不是第一次写了,比如斐波那契数列中的递归改非递归:
//递归实现斐波那契数列
#include <stdio.h>
int count = 0;
int Fid(int n)
{if (n <= 0)return 0;else if (n == 1)return 1;elsecount++;return Fid(n - 1) + Fid(n - 2);}int main()
{int n = 0;printf("请输入要求第几个斐波那契数列中的数字:>");scanf_s("%d", &n);int ret = Fid(n);printf("该数字为:%d\n", ret);printf("需要计算的次数为: %d\n", count);return 0;
}//迭代(循环)实现斐波那契数列
#include <stdio.h>
int count = 0;
int Fun(int n)
{int a = 1;int b = 1;int c = 1;while (n > 2) //当n>2时开始进行循环相加{c = a + b;a = b;b = c;count++;n--;}return c; //当n<2时直接输出1}int main()
{int n = 0;printf("请输入要求第几个斐波那契数列中的数字:>");scanf_s("%d", &n);int num = Fun(n);printf("该数字为:%d\n", num);printf("所需要的次数为:%d",count);return 0;
}
我们会发现,可以实现递归改迭代的问题,它们使用迭代实现的思路会比递归更加的好理解,所以一般来说我们在进行递归改非递归的过程中,会将递归改为迭代的形式。
但是对于快速排序而言,我们会利用栈来将它改为非递归的方式而不是迭代,这是因为在快速排序中,每次划分操作会将原始数组划分为两个较小的子数组。然后我们需要对这两个子数组进行进一步的划分和排序。这种嵌套关系导致了一个逻辑上的函数调用链。
使用循环来实现非递归版本时,我们无法直接模拟出函数调用链中各级函数之间传递参数和保存局部变量等信息的机制。而通过使用栈数据结构,在每次遇到新的待处理子数组时,我们可以将相关信息(如起始索引、结束索引)压入栈中,并在下一轮迭代时从栈中弹出并取出相应信息进行处理。
换句话说,通过利用栈作为辅助数据结构,在代码层面上模拟了逻辑上函数调用链所需传递和保存状态信息等功能。这样就能够以迭代方式按照特定顺序处理所有待处理子问题(即待切割和排序的子数组),达到完成整体排序任务。
结论:在非递归实现快速排序算法时选择使用栈来管理状态信息是一种常见且有效的策略
非递归快速排序
注意事项(重要)
我们利用栈存储的是每次要进行排序的数组元素的下标的值,而不是该数组元素的值,我们会将这些下标代入到之前实现过的单趟的快速排序中(比如伪双指针法快速排序),每次循环都进行一次单趟排序,这样就可以不再像递归那样排序时,需要借助栈帧
实现步骤
1、将数组首尾元素下标0和9入栈,将栈顶元素分别赋值给变量left和right后,栈顶元素出栈(赋值一个出一个,一共四步:入->出->入->出)将作left和right传入快速排序(其实就是begin和end)实现单趟排序
2、将单趟排序后形成的左区间和右区间的四个下标值入栈(单趟排序返回的是作为分界线元素的下标的值)
3、后续入栈出栈过程不予解释建议自行理解
代码实现
//非递归排序
void QuickSortNonR(int* a, int begin, int end)
{//初始化栈ST s;STInit(&s);//将数组首尾元素的下标的值作为x入栈STPush(&s, end);STPush(&s, begin);//栈不为空就循环while (!STEmpty(&s)){//获取栈顶元素值(原数组中的下标),并让栈顶元素出栈(获取完此时的栈顶元素就出,获取两个栈顶元素就开始排序)int left = STTop(&s);STPop(&s);int right = STTop(&s);STPop(&s);//将获取的两个下标值进行单趟排序(利用之前的伪双指针法)int keyi = PartSort3(a, left, right);// [left, keyi-1] keyi [keyi+1, right]//当左区间范围不为1时(没法继续缩小问题规模),将划分后左区间两个边界位置元素的下标值入栈if (left < keyi - 1){STPush(&s, keyi - 1);STPush(&s, left);}//当右区间范围不为1时(没法继续缩小问题规模),将划分后右区间两个边界位置元素的下标值入栈 if (keyi + 1 < right){STPush(&s, right);STPush(&s, keyi + 1);}}//最后销毁栈空间STDestroy(&s);
}
时空复杂度
最坏时间复杂度:O(N^2)(当输入数组完全有序时,每次切分操作都可能将数组分为一个较小的部分和一个较大的部分,导致每次切分只能减少一项)
最好时间复杂度:O(N*logN)(每次划分都能将数组均匀地分成两个接近子数组,N个元素要进行logN次的排序,N*logN,跟前面的递归排序的意思差不多)
空间复杂度:O(logN)(不需要额外的栈空间来保存状态信息,只需维护一个辅助堆栈用于存储待处理子数组的起止索引即可)
快速排序的特性
- 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
- 稳定性:不稳定
栈的相关代码
代码太多,就不再全部展示了,需要的自提:http://t.csdnimg.cn/kheGO
~over~
相关文章:

非递归实现的快速排序
目录 序列文章 前言 学前补充 非递归快速排序 注意事项(重要) 实现步骤 代码实现 时空复杂度 快速排序的特性 栈的相关代码 序列文章 非递归实现的快速排序:http://t.csdnimg.cn/UEcL6 快速排序的挖坑法与双指针法:ht…...

windows 安装jenkins
下载jenkins 官方下载地址:Jenkins 的安装和设置 清华源下载地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/windows-stable/ 最新支持java8的版本时2.346.1版本,在清华源中找不到,在官网中没找到windows的下载历史ÿ…...

SQL进阶理论篇(十二):InnoDB中的MVCC是如何实现的?
文章目录 简介事务版本号行记录的隐藏列Undo LogRead View的工作流程总结参考文献 简介 在不同的DBMS里,MVCC的实现机制是不同的。本节我们会以InnoDB举例,讲解InnoDB里MVCC的实现机制。 我们需要掌握这么几个概念: 事务版本号行记录的隐藏…...

SpringCloudAliBaba篇之Seata:分布式事务组件理论与实践
1、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中,一个事务由一组SQL语句组成,事务具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID原则。 原子性(atomici…...

在centos7.9上安装Jenkins的安装过程
1.jenkins的安装和配置: 安装JDK: yum install -y fontconfig java-11-openjdk # 安装目录:/usr/lib/jvm # fontconfig 是 Linux 系统中用于配置和管理字体的一种工具 下载jenkins安装包: sudo wget -O /etc/yum.repos.d/jenkins…...
uni-app基本标签
导航栏设置 - navigationBarBackgroundColor: 设置导航栏的背景颜色(全局页面) - navigationBarTextStyle: 导航栏标题颜色(仅支持 black 和 white) - navigationBarTitleText: 设置导航栏标题内容 - enablePullDownRefresh: 是否…...

《PySpark大数据分析实战》-14.云服务模式Databricks介绍基本概念
📋 博主简介 💖 作者简介:大家好,我是wux_labs。😜 热衷于各种主流技术,热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员(PCTA)、TiDB数据库专家(PCTP…...

微信小程序校园跑腿系统怎么做,如何做,要做多久
在这个互联网快速发展、信息爆炸的时代,人人都离不开手机,每个人都忙于各种各样的事情,大学生也一样,有忙于学习,忙于考研,忙着赚学分,忙于参加社团,当然也有忙于打游戏的&#x…...

当我分别问8款GPT一个问题。。。
前两天下班在地铁上无聊寻思问一下不同的GPT一个相同的问题,哪个会给出我比较满意的答案,然后我就提问:我老妹有点憨怎么办?(ps:开玩笑的,嘻嘻。。。) 很明显其他GPT都给出了大差不差…...
Elasticsearch 8.9 search命令执行查询源码
一、相关的API的handler1、接收HTTP请求的handler2、往数据节点发送查询请求的action(TransportSearchAction)3、通过transportService把查询请求发送到指定的数据节点 二、数据节点收到请求的处理逻辑1、尝试从缓存中加载查询结果2、不通过缓存查询,直接执行查询(1…...
【PHP】身份证正则验证、校验位验证
目录 1.正则 简单正则 详细正则 2.校验位验证 1.正则 简单正则 function isValidIdCardNumber($idCardNumber) {// 身份证号长度为 15 位或 18 位$pattern /^(?:\d{15}|\d{17}[\dxX])$/;return preg_match($pattern, $idCardNumber); }$idCardNumber 12345678901234567…...

Matlab示例-Examine 16-QAM Using MATLAB学习笔记
工作之余学习16-QAM 写在前面 网上看到许多示例,但一般都比较难以跑通。所以,还是老方法,先将matlab自带的例子研究下。 Examine 16-QAM Using MATLAB Examine 16-QAM Using MATLAB 或者,在matlab中,键入&#x…...
ArcGIS Pro SDK运行消息只提示一次
工具大部分都是异步执行,所以提示信息需要异步执行完再进行,所以注意async和await的使用。 相关async和await的文章请查看C# 彻底搞懂async/await_c# async await-CSDN博客 public async Task InformationPrompt() {string message String.Empty;await ArcGIS.De…...

通话状态监听-Android13
通话状态监听-Android13 1、Android Telephony 模块结构2、监听和广播获取通话状态2.1 注册2.2 通话状态通知2.3 通话状态 3、通知状态流程* 关键日志 frameworks/base/core/java/android/telephony/PhoneStateListener.java 1、Android Telephony 模块结构 Android Telephony…...

无懈可击的防泄密之旅:迅软DSE在民营银行的成功实践
客户简要介绍 某股份有限公司主体是中部地区的民营银行,由其母公司联合9家知名民营企业共同发起设立。正式开业于2016年,紧紧围绕目标产业生态圈和消费金融,着力打造产业银行、便捷银行、数字银行、财富管理银行为一体的BEST银行,…...

【送书活动】智能汽车、自动驾驶、车联网的发展趋势和关键技术
文章目录 前言01 《智能汽车》推荐语 02 《SoC底层软件低功耗系统设计与实现》推荐语 03 《SoC设计指南》推荐语 05 《智能汽车网络安全权威指南(上册)》推荐语 06 《智能汽车网络安全权威指南(下册)》推荐语 后记赠书活动 前言 …...

不同版本QT使用qmake时创建QML项目的区别
不同版本QT使用qmake时创建QML项目的区别 文章目录 不同版本QT使用qmake时创建QML项目的区别一、QT5新建QML项目1.1 目录结构1.2 .pro 文件内容1.3 main.cpp1.4 main.qml 二、QT6新建QML项目2.1 目录结构2.2 .pro文件内容2.3 main.cpp2.4 main.qml 三、两个版本使用资源文件的区…...

【PHP入门】1.1-PHP初步语法
-PHP语法初步- PHP是一种运行在服务器端的脚本语言,可以嵌入到HTML中。 1.1.1PHP代码标记 在PHP历史发展中,可以使用多种标记来区分PHP脚本 ASP标记: <% php代码 %>短标记: <? Php代码 ?>,以上两种…...

如何在jenkins容器中安装python+httprunner+pytest+git+allure(一)
背景: API接口自动化使用python语言实现,利用httprunner框架编写自动化用例场景(执行的时候还是依赖pytest),使用jenkins自动构建git上的源代码,并产生allure报告可视化展示API执行结果。 步骤 1.进入jenkins容器 注意使用roo…...
Android终端模拟器Termux上使用Ubuntu
Termux 上安装各种 Linux 系统是通过 proot-distro 工具来实现的,所以先安装一下 proot-distro 工具。 ~ $ pkg install proot-distro 查看Termux支持安装那些Linux ~ $ proot-distro listSupported distributions:* Alpine LinuxAlias: alpineInstalled: noComme…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...