有 $n$ 位同学的成绩已经从小到大排好序,现在对它执行下面这段以第一个元素为 pivot 的快速排序,请问此次排序的时间复杂度是( )。
void quicksort(vector<int>& a, int l, int r) {
if (l >= r) return;
int pivot = a[l];
int i = l, j = r;
while (i < j) {
while (i < j && a[j] >= pivot) j--;
while (i < j && a[i] <= pivot) i++;
if (i < j) swap(a[i], a[j]);
}
swap(a[l], a[i]);
quicksort(a, l, i - 1);
quicksort(a, i + 1, r);
}分析时间复杂度时关注循环层数和每层迭代次数,递归算法则分析递归树。注意最坏/最好/平均情况的区别。
分析复杂度时注意外层循环和内层循环的关联。例如内外两层都到n的循环不一定是O(n²),要看内层是否每次都在缩小。
1. 🎯 考纲定位 GESP 五级算法模块的典型陷阱题。命题人卡住的是"只会背 O(n log n) 平均复杂度"的考生——他们知道快速排序平均是 O(n log n),但没意识到当输入已有序且固定选第一个元素为 pivot 时,每次划分都极端失衡,退化成链表式递归。
2. 🧠 解题思维
3. 🪤 陷阱拆解
4. 🔄 反命题思维 若把 pivot 改成随机选(或选中间位置),已排序数据也能避免最坏情况,复杂度回归 O(n log n)。刷到类似题先问:pivot 怎么选?输入是否特殊?划分后左右段长度比例如何?