数据结构自学Day13 -- 快速排序--“非递归利用栈实现”

一、快速排序回顾

        快速排序本质上是**“分而治之”(Divide and Conquer)策略的递归应用。但递归其实就是函数栈的一种体现,因此我们也可以显式使用栈(stack)来模拟递归过程**,从而实现非递归版本的快速排序。

往期“快速排序算法回顾”:

快速排序--挖坑法
快速排序-- 分而治之

快速排序--前后指针法

注意:我们这里只是利用栈来模拟递归过程,递归算法会多次开辟额外的栈帧,利用栈的实现可以有效优化,避免爆栈。

🧱 二、利用栈实现非递归:

  1. 创建一个栈(保存左右区间的边界值);

  2. 把整个初始区间 [0, size-1] 入栈;

  3. 当栈不为空时:

    • 弹出一个区间 [left, right];

    • 对该区间做一次 Partition(分区);可利用前面我们学过的”前后指针“,”挖坑法“等

    • 得到划分下标 pivot;

    • 如果 [left, pivot-1] 有效,则入栈;

    • 如果 [pivot+1, right] 有效,则入栈;

  4. 重复,直到栈为空。

思维导图:

代码实现:

void QuickSort_stack(int* arr,int left,int right){assert(arr);if(left>=right){return;}int size = right+1;int* stack  = (int*)malloc(2*size*sizeof(int));//建立栈int top = 0;//先入左边,再入右边stack[top++] = left;stack[top++] = right;while (top>0){// 先进后出,所以先出右边int right  = stack[--top]; //注意 -- 的用法int left  = stack[--top];if(left<right){int div = PartSort2(arr,left,right); //利用分而治之的思想if(left<div-1){stack[top++] = left;stack[top++] = div-1;}if(div+1<right){stack[top++] = div+1;stack[top++] = right;}}}
}

三、递归以及栈调用对比

项目

递归版

非递归(栈模拟)

结构

简洁,易读

稍复杂,需维护栈

系统栈

占用系统调用栈

手动栈,控制更灵活

栈溢出风险

有,尤其数据近似有序

可优化,避免爆栈

应用场景

一般排序足够

资源受限场景、控制栈深度

可改进性

难以精细控制

可结合尾递归优化、栈平衡策略

四、📘 总结

栈实现快速排序的核心是把递归中“待处理的区间”压入一个显式栈,依次取出处理,用 迭代方式完成原本的递归流程。这样做不仅可以避免函数栈溢出,还可以为后续的性能优化提供空间。

 五、进一步优化建议

  1. 栈小区间优先处理(如先压小区间)可以避免栈过深;

  2. 对小区间(如 <16 元素)可以切换为插入排序,提高性能;

  3. 使用“三数取中”或“随机选主元”策略改善最坏情况;

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

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

相关文章

前端数据库:IndexedDB 基础使用

前言 在现代 Web 开发中&#xff0c;随着应用程序复杂度的增加&#xff0c;对本地存储的需求也越来越高。虽然 localStorage 和 sessionStorage 可以满足一些简单的数据存储需求&#xff0c;但当需要存储大量结构化数据或进行复杂查询时&#xff0c;它们就显得力不从心了。这时…

Kubernetes深度解析:企业级容器编排平台的核心实践

引言&#xff1a;Kubernetes的战略地位与核心价值在云原生技术生态中&#xff0c;​​Kubernetes​​已成为容器编排的事实标准。根据2023年全球云原生调查报告&#xff1a;全球​​96%​​ 的组织正在使用或评估Kubernetes企业生产环境Kubernetes采用率增长​​400%​​&#…

Netty中future和promise用法和区别

定义与概念 Future&#xff1a;表示一个异步操作的结果。它是只读的&#xff0c;意味着你只能查看操作是否完成、是否成功、获取结果或者异常等信息&#xff0c;但不能主动设置操作的结果。Promise&#xff1a;是 Future 的可写扩展。它不仅可以像 Future 一样查看操作结果&…

微算法科技(NASDAQ:MLGO)采用分布式哈希表优化区块链索引结构,提高区块链检索效率

随着区块链技术的快速发展&#xff0c;其在各个领域的应用越来越广泛。然而&#xff0c;区块链数据的存储和检索效率问题一直是制约其发展的瓶颈之一。为了解决这一问题&#xff0c;微算法科技(NASDAQ&#xff1a;MLGO)采用了分布式哈希表&#xff08;DHT&#xff09;技术来优化…

Jmeter的元件使用介绍:(三)配置元件详解01

Jmeter的配置元件有非常多&#xff0c;常用的有&#xff1a;信息头管理器、Cookie管理器、用户定义的变量、Http请求默认值、JDBC Connection Configuration、CSV 数据文件设置、计数器等&#xff0c;本文会对这些常用的配置元件一一介绍&#xff0c;还有其他很多配置元件&…

git 连接GitHub仓库

一、安装 git 包在官网下载 git 包二、通过SSH密钥与GitHub远程仓库连接1. 检查本地 SSH 密钥是否存在ls -al ~/.ssh如果看到 id_rsa 和 id_rsa.pub&#xff0c;说明已有密钥。2.如果没有&#xff0c;生成新的 SSH 密钥&#xff1a;ssh-keygen -t ed25519 -C "your_email…

如何通过AI扫描代码中的问题

代码质量其实在需求高压&#xff0c;业务快速迭代的场景下往往容易被人忽视的问题&#xff0c;大家的编码习惯和规范也经常会各有喜好&#xff0c;短期之内获取看不出来什么问题&#xff0c;但长此以往就会发现&#xff0c;屎山逐步成型了&#xff0c;而线上代码跑着往往就不想…

Java 大视界 -- Java 大数据机器学习模型在金融衍生品市场波动特征挖掘与交易策略创新中的应用(363)

Java 大视界 -- Java 大数据机器学习模型在金融衍生品市场波动特征挖掘与交易策略创新中的应用&#xff08;363&#xff09;引言&#xff1a;正文&#xff1a;一、Java 构建的金融数据处理架构1.1 多源异构数据实时融合1.2 新闻舆情与市场冲击建模二、Java 驱动的波动特征挖掘与…

Cartographer安装测试与模块开发(三)--Cartographer在Gazebo仿真环境下的建图以及建图与定位阶段问题(实车也可参考)

参数介绍之所以要首先介绍参数而不是实操&#xff0c;是因为大部分建图失败、漂移基本上都是参数设置错误引起的&#xff0c;或者说大部分都是TF存在问题&#xff0c;主要是坐标系Frame之间有冲突或者对不上等原因导致的&#xff0c;因此把参数放在前面介绍&#xff0c;了解了参…

uniapp nvue开发App 横竖屏切换丢失上下文导致 setTimeout和clearTimeout报错

报错内容如下 [JS Framework] Failed to find taskCenter (35). [JS Framework] Failed to execute the callback function:TypeError: c.clearTimeout is not a function reportJSException >>>> exception function:__WEEX_CALL_JAVASCRIPT__, exception:JavaSc…

Mirauge3D 赋能:全自动建模,让城市规划与建筑设计拥有高分辨率实景三维模型

在数字化浪潮席卷各行各业的当下&#xff0c;高精度、多元化的空间数据已成为基础测绘、智慧城市建设、自然资源管理等领域高质量发展的核心支撑。从城市交通网络的智能规划到国土空间的优化配置&#xff0c;从灾害监测的精准预警到生态环境保护的科学决策&#xff0c;空间数据…

Javaweb————学习javaweb的预备知识

❤️❤️❤️一.javase,javaweb,javaee的区别和联系 &#x1f499;&#x1f499;&#x1f499;javase: 通俗的来讲就是java技术栈&#xff0c;做java相关开发的基础&#xff0c;比如javaweb&#xff0c;javaee开发都是必备javase的基础的&#xff0c;包括java语言基础&#xff…

zabbix服务自动发现、自动注册及配置钉钉告警(小白的“升级打怪”成长之路)

目录 一、自动发现及自动注册 1、自动发现 2、自动注册规则 二、监控告警并发送电子邮件 1、设定发邮件的地址 2、设定发邮件的用户 3、设定监控及触发的条件 4、开始告警并设置触发发邮件 三、钉钉告警 1、配置zabbix-server 2、配置监控及触发 3、web页面操作 4、…

OSPF多区域

OSPF多区域划分的必要性 OSPF单区域存在的问题 LSDB 庞大&#xff0c;占用内存大&#xff0c;SPF计算开销大。 LSA洪泛范围大&#xff0c;拓扑变化影响范围大。 路由不能被汇总&#xff0c;路由表庞大&#xff0c;查找路由开销大 解决办法 划分区域可以解决上述问题 每个区域独…

质数、因数、最大公约数经典问题整理

1、计数质数 MX 5000000 is_prime [1] * MX is_prime[0] is_prime[1] 0 for i in range(2, MX):if is_prime[i]:for j in range(i * i, MX, i):is_prime[j] 0class Solution:def countPrimes(self, n: int) -> int:return sum(is_prime[:n]) 2、序列中不同最大公约数的…

Java NIO FileChannel在大文件传输中的性能优化实践指南

Java NIO FileChannel在大文件传输中的性能优化实践指南 在现代分布式系统中&#xff0c;海量数据的存储与传输成为常见需求。Java NIO引入的FileChannel提供了高效的文件读写能力&#xff0c;尤其适合大文件传输场景。本文从原理深度解析出发&#xff0c;结合生产环境实战经验…

SQLite Insert 语句详解

SQLite Insert 语句详解 SQLite 是一种轻量级的数据库管理系统,它以其简洁的设计、强大的功能和易于使用而闻名。在 SQLite 中,INSERT 语句用于向数据库表中添加新数据。本文将详细介绍 SQLite 的 INSERT 语句,包括其基本语法、使用方法以及一些高级特性。 基本语法 SQLi…

git更新内核补丁完整指南

Git操作完整指南 📋 目录 项目概述 Git基础配置 日常操作流程 补丁更新操作 分支管理 冲突解决 常见问题 最佳实践 命令速查表 🎯 项目概述 </

关于回归决策树CART生成算法中的最优化算法详解

首先&#xff0c;一共比如有M个特征&#xff0c;N个样本&#xff0c;对于每一个特征j&#xff0c;遍历其中的N个样本&#xff0c;得到N个值中&#xff0c;最小的值&#xff0c;作为这个特征的最优切分点&#xff0c;而其中的c1&#xff0c;c2是可以直接得到的。然后&#xff0c…

Ubuntu 环境下创建并启动一个 MediaMTX 的 systemd 服务

文章目录一、简介二、安装及使用三、创建系统服务小结一、简介 MediaMTX 是一个现代、高性能、跨平台的 流媒体服务器&#xff0c;主要用于接收、转发、转码和分发 音视频流&#xff0c;支持多种协议。它的前身是 rtsp-simple-server&#xff0c;后来重命名为 MediaMTX&#x…