用 Sorting-Algorithms-Blender 看懂归并排序:分治策略如何一步步合并出有序数组
【免费下载链接】Sorting-Algorithms-BlenderSorting algorithms visualized using the Blender Python API.项目地址: https://gitcode.com/gh_mirrors/so/Sorting-Algorithms-Blender
归并排序(Merge Sort)是算法学习中绕不开的经典排序算法,它的时间复杂度稳定在 O(n log n),而它背后的"分治策略"更是理解众多高级算法的钥匙。很多新手卡在"为什么先拆成一半,最后又能拼成有序数组"这一步,用 Sorting-Algorithms-Blender 项目把归并排序做成 3D 动画,就能直观看到每一层分解与合并的过程。这个开源项目基于 Blender Python API,把抽象的数组操作变成看得见的几何体运动,是入门归并排序可视化、学习分治思想的绝佳工具。
什么是归并排序?先搞懂"分治策略"这个核心思想
归并排序之所以高效,是因为它采用分治策略(Divide and Conquer),把一个大问题拆成若干小问题,逐个击破后再合并结果。整个过程只有三步:
- 分解(Divide):把数组从中间一分为二,得到两个子数组;
- 解决(Conquer):递归地对每个子数组继续分解,直到每个子数组只剩 1 个元素——单个元素天然有序;
- 合并(Combine):把两个已排序的子数组合并成一个更大的有序数组,逐层向上,最终得到完整的有序数组。
以[38, 27, 43, 3, 9, 82, 10]为例,动画中你会看到它先被拆成[38, 27, 43]和[3, 9, 82, 10],再继续拆到单个元素,然后从两个两个开始合并排序。排序顺序与分解顺序恰好相反,这也是归并排序最"反直觉"也最迷人的地方。
归并排序分治三步走:拆到不能再拆,再逐层合并
在 Sorting-Algorithms-Blender 里运行归并排序脚本,你能清楚看到两个阶段交替进行:
第一步:递归分解,直到单个元素
数组被不断从中间切开,动画中表现为物体不断被分成左右两组。这个过程的实现非常简洁,核心就是递归调用自身:
def merge_sort(arr, l, r): if l < r: m = l + (r - l) // 2 # 找到中点 merge_sort(arr, l, m) # 排序左半部分 merge_sort(arr, m + 1, r) # 排序右半部分 merge(arr, l, m, r) # 合并两个有序部分这段逻辑就在 merge_sort_scale.py 中,可以说是归并排序的"灵魂代码"。
第二步:合并有序子数组,关键在"双指针"
合并是归并排序的核心操作:同时比较两个有序子数组的头部元素,谁小谁先进入结果数组。动画中你能看到两边的物体被交替"挑选"出来,正是这个比较过程。
第三步:逐层归并,形成最终有序数组
每一层合并都会产生一个更大的有序子数组,直到顶层完成整个数组的排序。动画中观察这一层层的"收缩-排序-重组",比任何文字解释都直观。
用 Blender 看归并排序动画:4 种可视化风格任你选
Sorting-Algorithms-Blender 项目用 4 种不同方式呈现同一套归并排序逻辑,每种都值得运行一遍:
| 目录 | 可视化方式 | 数值表示 | 排序依据 |
|---|---|---|---|
| sort_scale | 立方体高度 | 位置 | 立方体缩放值 |
| sort_color | 平面渐变色 | 位置 | 材质红+绿通道 |
| sort_circle | 环形旋转体 | 旋转角度 | 材质 HSV 色相 |
| sort_combined | 立体立方体阵列 | 位置 | 多组 2D 数组 |
其中 merge_sort_scale.py 最"教学友好"——它用几何节点实时显示Comparisons(比较次数)和Array Accesses(数组访问次数)两个计数器,运行完一帧帧回放,就能直观感受归并排序的 O(n log n) 时间复杂度和 O(n) 空间复杂度从何而来。
跟着做:在 Blender 中运行归并排序脚本的 3 个步骤
想亲眼看到归并排序动画?只需三步,新手也能 5 分钟上手:
- 安装并启动 Blender(下载后直接打开即可);
- 打开脚本文件:在 Blender 的 Text Editor(文本编辑器)中打开任一归并排序脚本,例如 sort_circle/merge_sort_circle.py;
- 点击运行按钮:按下 Run Script,动画就自动生成,拖动时间轴即可回放整个归并排序过程。
想调整排序规模?只需修改脚本末尾的setup_array()参数,比如 merge_sort_color.py 中的setup_array(24),注意该脚本只接受偶数;而 merge_sort_circle.py 默认生成了 180 个元素,画面更为壮观。
归并排序的时间复杂度:为什么稳定在 O(n log n)?
看完整段动画,再回头理解复杂度就水到渠成了:
- 分解阶段:数组每次减半,共约 log₂n 层,每层处理 n 个元素,因此总复杂度为O(n log n);
- 最坏情况:无论数据如何排列,归并排序都要完整走完分解与合并,因此最好、平均、最坏情况都是 O(n log n),这一点在 README.md 的复杂度表中有完整标注;
- 空间复杂度:合并时需要临时数组存放左右子数组,所以额外空间为O(n),这是它不如堆排序、快速排序省内存的地方。
归并排序 vs 其他排序算法:一张表看懂差距
用 Sorting-Algorithms-Blender 依次运行其他排序脚本对比,会更容易建立"算法直觉":
| 算法 | 最好情况 | 平均情况 | 最坏情况 | 空间复杂度 |
|---|---|---|---|---|
| 归并排序 | Ω(n log n) | Θ(n log n) | O(n log n) | O(n) |
| 快速排序 | Ω(n log n) | Θ(n log n) | O(n²) | O(log n) |
| 堆排序 | Ω(n log n) | Θ(n log n) | O(n log n) | O(1) |
| 冒泡排序 | Ω(n) | Θ(n²) | O(n²) | O(1) |
| 插入排序 | Ω(n) | Θ(n²) | O(n²) | O(1) |
归并排序的最大优势是稳定且可预测——无论输入数据是正序、乱序还是逆序,性能都不会退化,这也是它常被用于数据库排序、外部排序的底层原因。其他排序脚本分别位于 sort_color、sort_scale 与 sort_circle 目录,搭配观看对比效果更佳。
总结:把归并排序"看"明白,分治思想自然就懂了
归并排序的本质一句话就能概括:不断对半拆、有序地合。而 Sorting-Algorithms-Blender 把这句话变成了一部生动的 3D 动画——物体一次次被分开、又一次次按序归位,整个过程清晰呈现"分治策略"如何一步步合并出有序数组。如果你想彻底掌握归并排序,不妨克隆仓库(git clone https://gitcode.com/gh_mirrors/so/Sorting-Algorithms-Blender)亲手运行一遍动画;看懂它的那一刻,你会觉得算法的世界突然变得简单又美丽。🚀
【免费下载链接】Sorting-Algorithms-BlenderSorting algorithms visualized using the Blender Python API.项目地址: https://gitcode.com/gh_mirrors/so/Sorting-Algorithms-Blender
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考