跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

快速排序非递归实现详解

快速排序非递归实现利用显式栈结构模拟系统调用栈,解决递归深度过大导致的栈溢出问题。核心在于手动管理待排序区间的入栈与出栈顺序,优先处理左子区间以维持递归逻辑。文章提供基于快慢指针分区法的 C++ 代码示例,展示如何通过堆内存扩展空间安全性,并分析其在极端数据下的性能优化潜力。

DotNetGuy发布于 2026/3/28更新于 2026/10/2377 浏览
快速排序非递归实现详解

非递归快速排序实现

一、核心原理与思路

1.1 核心原理:手动模拟栈

在标准的递归快速排序中,系统会自动分配函数调用栈来记录当前的 left 和 right 以及返回位置。在非递归版本中,我们不需要系统帮忙,而是自己创建一个栈(Stack)数据结构。

1.2 核心操作:用栈存取数组区间

① 向栈中存储操作:存储每一次需要排序的子数组的起止下标(begin,end)。由于栈的特性是先进后出,优先处理左区间,再处理右区间,类似于二叉树的前序遍历。故而在存储的时候优先存储右区间,再进行存储左区间。 ② 向栈中拿取操作:每次从栈里拿出一对下标,对这段范围进行'分区操作',然后把产生的新范围(左半区和右半区)再扔回栈里。

二、用栈来模拟存储区间

假设存在数组 a 为:[6, 1, 2, 3, 4, 5, 9, 7, 10, 8] 下标:[0 1 2 3 4 5 6 7 8 9] 定义 int left1:左区间数组的起始位置下标 定义 int right1:左区间数组的终止位值下标 则左区间数组的范围是:[left1 , right1] 定义 int left2:右区间数组的起始位置下标 定义 int right2:右区间数组的终止位置下标 则右区间数组的范围是:[left2,right2]

第一步:初始化栈 准备一个空栈,先把整个数组的任务扔进去:入栈:[0, N-1] 第二步:循环处理 这是一个 while(栈非空) 的循环:

  1. 弹栈(Pop):拿出一个任务(begin,end)。
  2. 分区(Partition):通过 Hoare 分区法进行分割当前处理任务,keyi = PartitionSlowFast(a, begin, end); 将其分为 [begin , keyi - 1] keyi [keyi+1 , end]
  3. 记录左右区间:记录左区间 left1 = begin right1=keyi-1;记录右区间 left2 = keyi+1 right2=end。
  4. 入栈左右区间:优先压入右区间,再压入左区间,因为栈是'后进先出',这样下一轮循环就会先处理左边,模拟递归的顺序。 (💡 小贴士:区间只有一个元素不入栈,区间不存在也不入栈) 第三步:栈为空 当栈变空时,说明所有的大区间都被切成了小区间,小区间都被切没了(排序完成),数组就有序了!

三、代码实现

#include <iostream>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;

// 1. 实现快慢指针法分区 (PartitionSlowFast)
int PartitionSlowFast(int* a, int left, int right) {
    int keyi = left;
    int prev = left;
    int cur = left + 1;
     (cur <= right) {
         (a[cur] < a[keyi] && ++prev != cur) {
            (a[prev], a[cur]);
        }
        cur++;
    }
    (a[keyi], a[prev]);
     prev;
}


{
    stack<> st;
     (left < right) {
        st.(right);
        st.(left);
    }
     (!st.()) {
         begin = st.(); st.();
         end = st.(); st.();
         keyi = (a, begin, end);
        
         left2 = keyi + ;
         right2 = end;
         (right2 - left2 >= ) {
            st.(right2);
            st.(left2);
        }
        
         left1 = begin;
         right1 = keyi - ;
         (right1 - left1 >= ) {
            st.(right1);
            st.(left1);
        }
    }
}
while
if
swap
swap
return
// 2. 非递归快速排序主函数
void QuickSortNonR(int* a, int left, int right)
int
if
push
push
while
empty
int
top
pop
int
top
pop
int
PartitionSlowFast
// 处理右区间 [keyi+1, end]
int
1
int
if
1
push
push
// 处理左区间 [begin, keyi-1]
int
int
1
if
1
push
push

四、非递归实现快排的优势

4.1 防止栈溢出

递归的深度是有限制的。如果数组极其巨大,或者处于最坏情况,递归层数太深会导致程序崩溃。非递归使用堆内存(Heap)来存栈,空间通常比系统栈大得多,更安全。

4.2 性能优化

在某些极端环境下,函数调用本身是有开销的(保存现场、恢复现场),手动模拟可以省去这些微小的开销。

目录

  1. 非递归快速排序实现
  2. 一、核心原理与思路
  3. 1.1 核心原理:手动模拟栈
  4. 1.2 核心操作:用栈存取数组区间
  5. 二、用栈来模拟存储区间
  6. 三、代码实现
  7. 四、非递归实现快排的优势
  8. 4.1 防止栈溢出
  9. 4.2 性能优化

更多推荐文章

查看全部
  • 稳健回归模型对异常值的抵御
  • 大语言模型微调指南:LoRA 原理与实践代码
  • 深度解析 OpenVR、OpenXR、SteamVR 与厂商 SDK 的核心差异
  • Python 入门实战:从 Hello World 到变量使用详解
  • 基于 BERT+Seq2Seq 架构的智能对话系统构建指南
  • RabbitMQ 核心工作模式详解与 Java 实战
  • AC-MPC:微分 MPC 赋能强化学习,实现高速无人机竞速
  • 论文查重前必备的 5 款 AIGC 检测工具推荐
  • SkyWalking 与 Spring Cloud Alibaba 全链路追踪实战
  • 网络安全入门核心知识点与技能体系梳理
  • OpenClaw 多飞书机器人接入与多 Agent 团队协作实战
  • Python 开发常用库与框架资源指南
  • 插件式开发实战:C++ 与 C# 下的软件解耦方案
  • C++ 笔试刷题 Day 11:水果礼包、股票买卖与字符串倒置
  • Java Lambda 与匿名内部类为何不能修改外部变量?final 机制解析
  • 使用基础模型自动化寻找人工生命 - MIT&OpenAI&Sakana AI
  • 大数据视角下时序数据库选型:Apache IoTDB 核心优势解析
  • Stable Diffusion v1.5 Archive 跨平台效果一致性保障与复现验证
  • Vue Beauty UI 组件库核心功能梳理
  • AI 小白的大模型学习路径与核心概念解析

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online