什么是数组快排
快速排序是一种:
分治思想的排序算法
平均时间复杂度 O(n log n)
原地排序(不需要额外数组)
实际中 非常快(STL sort 的核心思想之一)
核心一句话:
选一个 " 基准值 " ,把数组分成 " 比它小的 " 和 " 比它大的 " ,递归排序
快排的直觉理解
假设有数组:
5, 1, 6, 2, 4, 3
① 选一个基准值
一般选:
第一个元素
最后一个元素
或中间元素
比如选 5作为基准值
② 一趟划分
目标是:
左边 <= 5 | 5 | >= 5 右边
执行完一趟后,5 会到它最终该在的位置。
结果可能变成:
3, 1, 4, 2\] 5 \[6
注意:
左右两边不一定有序
但 5 的位置已经确定,不会再动
③ 递归排序左右两部分
对左边 [3,1,4,2] 再做快排
对右边 [6] 不用排
快排的核心: 划分
常见做法:左右指针法(最经典)
假设:
pivot = a[l]
i = l
j = r
步骤:
- 从右往左找 < pivot 的
- 从左往右找 > pivot 的
- 交换它们
- 重复,直到 i == j
- 把 pivot 放到中间位置
代码:
cpp
void quickSort(int a[], int l, int r)
{
if (l >= r) return;
int pivot = a[l];
int i = l, j = r;
while (i < j)
{
// 从右往左找比 pivot 小的
while (i < j && a[j] >= pivot) j--;
// 从左往右找比 pivot 大的
while (i < j && a[i] <= pivot) i++;
if (i < j)
swap(a[i], a[j]);
}
// pivot 放到正确位置
swap(a[l], a[i]);
quickSort(a, l, i - 1);
quickSort(a, i + 1, r);
}
时间复杂度
|-----------|------------|
| 情况 | 复杂度 |
| 平均 | O(n log n) |
| 最坏(已排序数组) | O(n²) |
为了避免最坏情况,实际中会:
随机选 pivot
或三数取中
链表归并排序核心思想
分:用快慢指针把链表从中间断开
治:递归排序左右两条链表
合:合并两个有序链表
完美适配链表结构。
链表节点定义
cpp
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
主函数:链表归并排序
cpp
ListNode* mergeSortList(ListNode* head)
{
// 递归结束条件
if (!head || !head->next)
return head;
// 快慢指针找中点
ListNode* slow = head;
ListNode* fast = head->next;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
// 断开链表
ListNode* mid = slow->next;
slow->next = nullptr;
// 递归排序左右部分
ListNode* left = mergeSortList(head);
ListNode* right = mergeSortList(mid);
// 合并两个有序链表
return mergeTwoLists(left, right);
}
合并两个有序链表
cpp
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
{
ListNode dummy(0);
ListNode* tail = &dummy;
while (l1 && l2)
{
if (l1->val <= l2->val)
{
tail->next = l1;
l1 = l1->next;
}
else
{
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
// 接上剩余部分
tail->next = l1 ? l1 : l2;
return dummy.next;
}
复杂度分析(面试必说)
|--------|-------------------|
| 项目 | 复杂度 |
| 时间复杂度 | O(n log n) |
| 空间复杂度 | O(log n)(递归栈) |
| 是否稳定 | 稳定 |
| 是否原地 | (不新建节点) |
为什么链表「一定选归并排序」
三大理由:
不需要随机访问
合并链表天然 O(n)
稳定排序、实现简洁