0

0

c++如何实现快速排序_c++快排算法源码分析【进阶】

尼克

尼克

发布时间:2026-02-11 14:49:02

|

695人浏览过

|

来源于php中文网

原创

std::sort 实际是 introsort 而非纯快排:先快排,深度超限切堆排序,小数组切插入排序;手写快排用于调试、教学、嵌入式或定制化需求,常见崩溃源于 pivot 选择不当和边界越界。

c++如何实现快速排序_c++快排算法源码分析【进阶】

为什么 std::sort 不等于手写快排

标准库的 std::sort 在绝大多数场景下不是纯快排,而是 introsort(内省排序):先用快排,递归深度超阈值时切到堆排序,小数组再切到插入排序。直接调 std::sort 虽快且稳,但无法控制分区策略、pivot 选取或递归行为——这正是你手写快排的真正动机:调试、教学、嵌入式约束,或定制化(比如按内存局部性优化 partition)。

手写快排最常崩在 pivot 选择和边界处理

崩溃往往不是逻辑错,而是越界访问或无限递归。典型诱因:

  • partition 函数里用 while (left 却没保证 leftright 永远不越界;
  • 选 pivot 用 v[0]v[size-1],遇到已排序数组退化成 O(n²),栈溢出风险陡增;
  • 递归调用写成 quick_sort(v, left, right) 而非 quick_sort(v, left, pivot_idx - 1),漏减 1 导致死循环;
  • 没对长度 ≤ 1 的子数组做 early return,空区间也进递归。

一个生产级可读的手写快排(Lomuto + 三数取中)

以下代码避开常见坑,兼顾清晰与鲁棒性:

void quick_sort(std::vector& v, int left = 0, int right = -1) {
    if (right == -1) right = v.size() - 1;
    if (left >= right) return;
// 三数取中选 pivot,避免最坏情况
int mid = left + (right - left) / 2;
if (v[mid] zuojiankuohaophpcn v[left]) std::swap(v[left], v[mid]);
if (v[right] zuojiankuohaophpcn v[left]) std::swap(v[left], v[right]);
if (v[right] zuojiankuohaophpcn v[mid]) std::swap(v[mid], v[right]);
std::swap(v[mid], v[right]); // pivot 放末尾

// Lomuto partition:i 是小于 pivot 的右边界
int i = left;
for (int j = left; j zuojiankuohaophpcn right; ++j) {
    if (v[j] zuojiankuohaophpcn= v[right]) {
        std::swap(v[i++], v[j]);
    }
}
std::swap(v[i], v[right]); // pivot 归位

quick_sort(v, left, i - 1);
quick_sort(v, i + 1, right);

}

立即学习C++免费学习笔记(深入)”;

Flowith
Flowith

一款GPT4驱动的节点式 AI 创作工具

下载

关键点:right == -1 做默认参数适配;mid 计算用 left + (right - left) / 2 防整型溢出;partition 后明确用 i-1i+1 划分,不碰 pivot 位置。

迭代版快排为什么难写对

用栈模拟递归看似能防栈溢出,但错误率更高:容易漏 push 子区间、push 顺序反了(导致降序变升序)、或忘记 pop 后校验区间有效性。更现实的做法是限制递归深度——比如当 right - left > 1000 时改用 std::partial_sort 或堆排序分支。真要迭代,优先用 std::stack<:pair int>> 存区间,别手撸链表栈。

最易被忽略的是:快排的“快”高度依赖数据分布和 cache 行命中率,而非算法本身。同一份源码,在随机数据、升序数据、含大量重复值的数据上,性能可能差 5 倍以上——测之前,先想清楚你的真实输入长什么样。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

399

2023.09.04

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

101

2023.09.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

688

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

557

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

206

2025.08.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

409

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

586

2023.08.10

2026春节习俗大全
2026春节习俗大全

本专题整合了2026春节习俗大全,阅读专题下面的文章了解更多详细内容。

68

2026.02.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.2万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号