0

0

c++中如何实现归并排序_c++分治思想归并排序算法【详解】

尼克

尼克

发布时间:2026-01-18 11:07:02

|

426人浏览过

|

来源于php中文网

原创

归并排序的核心是分治三步:split切分、merge合并、combine写回;merge需用临时数组、半开区间、正确边界控制,且应复用辅助空间而非重复分配。

c++中如何实现归并排序_c++分治思想归并排序算法【详解】

归并排序的核心逻辑是分治,不是递归本身

归并排序的正确理解起点不是“写个递归函数”,而是明确三步:split(切分到单元素)、merge(合并两个有序段)、combine(把合并结果写回原数组)。递归只是实现 split 的自然手段,但容易让人忽略 merge 的边界控制——这才是实际编码出错最多的地方。

  • 切分时用 [left, right) 半开区间比 [left, right] 更少出错,避免 mid = (left + right) / 2 溢出可改用 mid = left + (right - left) / 2
  • merge 必须用临时数组暂存结果,不能边合并边写回原数组,否则会覆盖未读取的数据
  • 合并循环的终止条件不是“两个子数组都空”,而是“至少一个已耗尽”,剩余部分直接拷贝

标准实现中 merge 函数的四个关键参数

很多初学者把 merge 写成只接受两个独立数组的函数,这在归并排序里反而增加复杂度。实际应传入原数组指针 + 三段下标:arrleftmidrightmid 是左半段末尾+1,即右半段起始位置)。

  • leftmid-1 是左有序段
  • midright-1 是右有序段
  • 合并结果要填回 arr[left]arr[right-1]
  • 临时数组大小必须是 right - left,而非固定长度或 arr.size()

避免内存重复分配的常见优化

每次递归都 new 临时数组会导致大量堆分配,尤其对大数组性能敏感。更合理的方式是在顶层调用时一次性分配好辅助空间,全程复用。

INFINITE ALBUM
INFINITE ALBUM

面向游戏玩家的生成式AI音乐

下载
void mergeSort(vector<int>& arr) {
    if (arr.size() <= 1) return;
    vector<int> temp(arr.size()); // 一次分配
    mergeSortHelper(arr, temp, 0, arr.size());
}
<p>void mergeSortHelper(vector<int>& arr, vector<int>& temp, int left, int right) {
if (right - left <= 1) return;
int mid = left + (right - left) / 2;
mergeSortHelper(arr, temp, left, mid);
mergeSortHelper(arr, temp, mid, right);
merge(arr, temp, left, mid, right);
}
  • temp 作为引用传入,避免拷贝
  • merge 内部只操作 temp 的对应区间,再批量拷贝回 arr
  • 若用原始指针(如 int*),需额外传入 temp 起始地址,逻辑不变

迭代版归并排序为什么更难写对

递归版天然体现分治结构,而迭代版靠自底向上合并:先两两合并长度为 1 的段,再合并长度为 2 的段……容易错在 right 边界越界和最后一段长度不足时的处理。

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

  • 外层循环步长 len 从 1 开始,每次翻倍:for (int len = 1; len
  • 内层循环起点 i 每次加 2 * len,但 right = min(i + 2 * len - 1, n - 1) 必须取最小值
  • 右半段可能不存在(i + len >= n),此时跳过合并
  • 即使知道原理,手写迭代版仍建议先跑通递归版,再对照改写,否则调试成本极高

归并排序真正卡住人的地方,从来不是“怎么分”,而是“合并时下标算错一格,整段结果就乱序”,尤其是 midright 的开闭关系、临时数组拷贝的起始偏移。写完务必用 {5, 2, 4, 7, 1} 这类小样例单步验证 merge 调用前后的子数组内容。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
string转int
string转int

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

970

2023.08.02

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

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

605

2024.08.29

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

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

294

2025.08.29

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

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

212

2025.08.29

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

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

435

2023.07.18

堆和栈区别
堆和栈区别

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

601

2023.08.10

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

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

435

2023.07.18

堆和栈区别
堆和栈区别

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

601

2023.08.10

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Rust 教程
Rust 教程

共28课时 | 6.6万人学习

Git 教程
Git 教程

共21课时 | 4.1万人学习

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

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