标准答案(严谨学术版)
主流排序算法全览
算法 | 类型 | 时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|
冒泡排序 | 比较排序 | O(n²) (全情况) | O(1) | 稳定 |
插入排序 | 比较排序 | O(n²) (最坏/平均) → O(n) (最好) | O(1) | 稳定 |
选择排序 | 比较排序 | O(n²) (全情况) | O(1) | 不稳定 |
快速排序 | 比较排序 | O(n log n) (平均/最好) → O(n²) (最坏) | O(log n) | 不稳定 |
归并排序 | 比较排序 | O(n log n) (全情况) | O(n) | 稳定 |
堆排序 | 比较排序 | O(n log n) (全情况) | O(1) | 不稳定 |
计数排序 | 非比较排序 | O(n + k) (k为数值范围) | O(k) | 稳定 |
桶排序 | 非比较排序 | O(n + n²/k + k) → 最优O(n) | O(n + k) | 稳定 |
基数排序 | 非比较排序 | O(d(n + k)) (d为位数) | O(n + k) | 稳定 |
人类程序员的奇幻脑洞
1. 冒泡排序:算法界的复读机
这货就像你妈催你穿秋裤 👖:
- “这个比下一个大?换位置!”
- “这个比下一个大?换位置!”
(循环直到全体有序)
代码の终极奥义:
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j] # 左右互搏术
return arr
💡 冷知识:当数组已排序时,优化版冒泡可提前退出,但实战中没人用——就像你知道不用秋裤但妈妈觉得你冷 ❄️
2. 快速排序:分治の暴走族
快排的日常就是:“拆!拆!拆!” 🔨
- 随便抓个基准值(比如中间那个)
- 左派(小值)右派(大值)站队
- 左右继续搞分裂
代码の血腥现场:
void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high); // 分而治之
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
// 分区函数才是真の杀器
private int partition(int[] arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j=low; j<high; j++) {
if (arr[j] < pivot) {
i++;
swap(arr, i, j); // 不服就干!
}
}
swap(arr, i+1, high);
return i+1;
}
⚠️ 血泪史:如果选到极值当基准,递归深度直接变O(n),StackOverflowError教你做人!
3. 归并排序:温柔の缝合怪
归并像学霸整理笔记 📒:
- 把书撕成两半(递归拆分)
- 每半都整理好
- 用胶水仔细粘合并
代码の治愈时刻:
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right); // 开始缝合!
}
function merge(left, right) {
let result = [];
while (left.length && right.length) {
result.push(left[0] < right[0] ? left.shift() : right.shift());
}
return [...result, ...left, ...right];
}
🌪️ 隐藏技能:处理海量数据时常用外排序(归并+分块加载),堪称磁盘IOの救星!
算法迷因大乱斗
面试官の灵魂拷问
面试官:假设你有10GB数据要排序,但内存只有2GB,怎么办?
萌新:我…我加内存条? 💾
老手:用外部归并排序,分块读取→内部排序→合并写入! 🧠
大神:直接上Hadoop搞MapReduce,顺便把面试官电脑当节点 🖥️💥
免责声明
- 本文时间复杂度计算忽略常数项,实际编码时若因
for循环多写一层
导致性能不达标,请默念"我是面向工资编程" - 文中提到的"撕书行为"请勿模仿,损坏教材请自费购买
- 若在约会时突然思考排序算法,导致被甩,作者提供精神慰问但不承担恋爱咨询费用 💔
- 所有代码示例均可Ctrl+C/V,但建议手敲一遍以加深对报错信息的理解 🐛
(完)