P1177 【模板】排序
题目描述
将读入的 \(N\) 个数从小到大排序后输出。
输入格式
第一行为一个正整数 \(N\)。
第二行包含 \(N\) 个空格隔开的正整数 \(a_i\),为你需要进行排序的数。
输出格式
将给定的 \(N\) 个数从小到大输出,数之间空格隔开。
输入输出样例 #1
输入 #1
输出 #1
说明/提示
对于 \(20\%\) 的数据,有 \(1 \leq N \leq 10^3\);
对于 \(100\%\) 的数据,有 \(1 \leq N \leq 10^5\),\(1 \le a_i \le 10^9\)。
好,这题是排序模板题 + 快排实现,我按你刚定的格式来👇
📌 题目分析
👉 本质: 把一个数组按从小到大排序
👉 类型: 排序算法(快速排序)
🧠 解题思路
1️⃣ 核心建模
输入一个数组 a[i],要求:
2️⃣ 性质分析
👉 排序问题的常见解法:
- 快速排序(本题要求)
- 归并排序
- STL sort(底层快排+优化)
👉 这里重点:手写快速排序
3️⃣ 算法选择(快速排序)
核心思想:
4️⃣ 快排核心步骤(必须掌握)
假设区间 [l, r]
✔ 1. 选基准
✔ 2. 双指针分区
int i = l, j = r;
while (i <= j) {
while (a[i] < pivot) i++;
while (a[j] > pivot) j--;
if (i <= j) {
swap(a[i], a[j]);
i++, j--;
}
}
✔ 3. 递归
5️⃣ 关键细节(非常重要)
- pivot 选中间 → 防止退化
- 必须
i <= j(不是<) - 递归边界不能写错
- 数据量 1e5 → 快排 OK
6️⃣ 时间复杂度
- 平均:
O(n log n)✅ - 最坏:
O(n^2)(已通过 pivot 优化降低概率)
💻 C++代码(手写快排)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int a[N];
int n;
void quick_sort(int l, int r) {
if (l >= r) return;
int i = l, j = r;
int pivot = a[(l + r) >> 1]; // 选中间值
while (i <= j) {
while (a[i] < pivot) i++;
while (a[j] > pivot) j--;
if (i <= j) {
swap(a[i], a[j]);
i++, j--;
}
}
if (l < j) quick_sort(l, j);
if (i < r) quick_sort(i, r);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
quick_sort(0, n - 1);
for (int i = 0; i < n; i++) {
cout << a[i] << " ";
}
return 0;
}
⚠️ 易错点
❌ 1. 死循环
✅ 必须:
❌ 2. 递归区间写错
✅ 正确:
❌ 3. pivot 选错
✅ 推荐:
❌ 4. 忘记边界判断