排序算法简介

欢迎!在本章中,我们将探讨计算机科学中最基础的任务之一:排序 (Sorting)。无论你是在 Amazon 上筛选最便宜的商品,还是浏览社交媒体上朋友的最新贴文,幕后都有排序算法在处理这些数据,确保它们以正确的顺序呈现。

对于 AQA A Level 课程,你需要掌握两种特定的算法:冒泡排序 (Bubble Sort)归并排序 (Merge Sort)。我们将研究它们的运作方式、如何一步步进行演算,以及它们的效率如何。如果起初觉得有些抽象也不用担心,我们会使用大量的现实生活比喻,让你轻松掌握!

预备概念:请记住,数组 (Array) 其实就是一个项目的列表。排序的过程就是将这些项目(通常是数字)重新排列为升序(从小到大)。


1. 冒泡排序 (Bubble Sort)

冒泡排序通常是学生学习的第一种排序算法。它以简单易懂著称,但正如你之后会看到的,对于大量数据来说,它的速度并不快!

运作方式:“上升气泡”比喻

想象汽水里的一串气泡。更大、更“重”的气泡会浮到上面。在冒泡排序中,算法会遍历列表,比较相邻的项目,如果顺序错误就将它们交换 (Swap)。这个过程会不断重复,直到最大的数字像“气泡”一样浮到列表的最末端。

步骤拆解

1. 从列表的最开头开始。
2. 比较前两个项目。
3. 如果第一个项目大于第二个,就进行交换
4. 移动到下一对项目并重复此步骤,直到列表结束(这称为一轮扫描/Pass)。
5. 对整个列表重复上述过程,直到某次扫描过程中完全没有发生任何交换为止。

让我们试着演练一次!

假设我们有这个列表:[5, 1, 4]

第一轮扫描 (Pass 1):
• 比较 5 和 1。5 比 1 大,进行交换。列表变为:[1, 5, 4]
• 比较 5 和 4。5 比 4 大,进行交换。列表变为:[1, 4, 5]
数字 5 现在已经“浮”到了最后面!

第二轮扫描 (Pass 2):
• 比较 1 和 4。1 较小,不交换
• 比较 4 和 5。4 较小,不交换
这一轮没有进行任何交换,所以列表已经排序完成!

效率与复杂度

冒泡排序被认为是一种效率极低的算法。如果你有一个包含 \(n\) 个项目的列表,你可能需要将每个项目与其他所有项目进行比较。

时间复杂度: \(O(n^2)\)(多项式时间)。
为什么? 因为它使用了嵌套循环 (Nested loops)——一个循环用来遍历列表,另一个循环则持续重复进行扫描。

快速复习:
最适用于:非常小的列表,或是已经几乎排好序的列表。
常见错误:以为扫描一次列表就排序完成了。你必须持续进行扫描,直到完全没有发生交换为止!

关键要点:冒泡排序简单但速度慢。其时间复杂度为 \(O(n^2)\)。


2. 归并排序 (Merge Sort)

对于大型列表,归并排序比冒泡排序快得多。它使用了一种聪明的策略,称为分治法 (Divide and Conquer)

运作方式:“扑克牌”比喻

想象你有一堆杂乱的 100 张扑克牌。要一次把它们全排好很难。但如果你把它们分成两堆各 50 张,再分成四堆各 25 张,一直分下去直到剩下 100 堆各只有 1 张牌……嗯,只有 1 张牌的那一堆已经算“排好序”了!然后,你只需要小心地将这些堆按正确顺序合并 (Merge) 回来即可。

分治阶段

阶段 1:拆分 (Divide)

算法不断将列表一分为二,直到每个子列表只剩下一个元素。根据定义,只有一个元素的列表本身就是排好序的。

阶段 2:合并 (Conquer/Merge)

随后,算法将这些子列表合并回来。在合并过程中,它会比较每个子列表前端的项目,并将较小的一个先放入新的组合列表中。

演练归并排序

列表:[8, 3, 5, 1]

步骤 1 (拆分): 分成 [8, 3][5, 1]
步骤 2 (拆分): 分成 [8], [3], [5], [1]
步骤 3 (合并):[8][3] 合并为 [3, 8]。将 [5][1] 合并为 [1, 5]
步骤 4 (合并): 合并 [3, 8][1, 5]。比较 3 和 1(1 较小),然后比较 3 和 5(3 较小),接着比较 8 和 5(5 较小),最后剩下 8。结果:[1, 3, 5, 8]

效率与复杂度

由于归并排序每次都会将列表对半分割,它的效率远高于冒泡排序。

时间复杂度: \(O(n \log n)\)。
为什么? 「\(\log n\)」来自于我们能将列表对半分割的次数,而「\(n\)」则来自于将项目合并回来所需的处理工作。

你知道吗? 归并排序比冒泡排序需要更多的内存(空间复杂度),因为在过程中必须建立新的子列表!

关键要点:归并排序是一种“分治”算法,时间复杂度为 \(O(n \log n)\)。


总结比较表

冒泡排序
• 方法:交换相邻项目。
• 复杂度: \(O(n^2)\)。
• 效能:,处理大量数据时效率低下。

归并排序
• 方法:分治法 (Divide and Conquer)
• 复杂度: \(O(n \log n)\)。
• 效能:,处理大量数据时效率高。


快速复习:检查你的理解

• 哪一种算法是“分治法”的例子?(答案:归并排序
• 冒泡排序的时间复杂度是多少?(答案: \(O(n^2)\))
• 为什么冒泡排序被认为效率低下?(答案:它需要多次扫描和比较,特别是当列表变大时。)
• 如果你有一个包含 100 万用户的庞大数据库,你应该使用哪种排序?(答案:归并排序,因为对于较大的 \(n\) 值, \(O(n \log n)\) 比 \(O(n^2)\) 快得多。)

如果觉得演练归并排序的过程有点“递归”或绕口也不用担心!只要记住核心概念:拆分到只剩单个,然后依序缝合起来。