难度:进阶。题目原型为洛谷 U104252 基数排序模板(私题,题面自定)。本题的考点是 LSD 基数排序:不比较元素大小,而是按十进制位从低位到高位逐位做稳定排序,每轮借助计数排序在 O(n+k) 内完成。
目标
完成本题后,你应该能够:
- 说出基数排序为什么必须用稳定排序处理每一位;
- 独立写出「计数排序 + 按位循环」的 LSD 基数排序模板;
- 说明时间复杂度
O(d(n+k))中d、k各是什么。
前置知识
- 计数排序(对整数范围的稳定排序);
- 十进制数位提取:
(x / exp) % 10。
题目
读入 n 个非负整数,用基数排序把它们从小到大输出。
输入格式
- 第一行一个整数
n; - 第二行
n个非负整数,以空格分隔。
输出格式
一行 n 个从小到大排好序的整数,以空格分隔。
数据范围
| 项目 | 范围 |
|---|---|
整数个数 n | 1 ≤ n ≤ 10⁵ |
| 元素值 | 0 ≤ a[i] ≤ 10⁹ |
样例
样例输入
input
6
329 457 657 839 436 720样例输出
output
329 436 457 657 720 839样例解释
LSD 基数排序从个位开始,依次按十位、百位……做稳定计数排序。上面的数据只需 3 轮(个位、十位、百位)即可排好。
如何验证
先安装 Node.js、pnpm 和支持 C++17 的编译器。
powershell
# 已进入本 Lab 目录
make doctor
make run
make run CASE=001-sample
make interactive
make scoreWindows 没有安装 Make 时,在仓库根目录使用等价的 pnpm 入口:
powershell
pnpm lab:run -- labs/chapter-11/exercise/E-11-17-radix-sort-template
pnpm lab:score -- labs/chapter-11/exercise/E-11-17-radix-sort-template标准输出参与判题,调试信息请写入标准错误。
完成清单
思考题
- 如果把每轮的计数排序换成不稳定的排序,结果会错在哪里?举一个反例。
- 处理的轮数
d由什么决定?为什么值域 10⁹ 最多需要 10 轮? - 基数排序适合什么场景?什么时候反而不如
std::sort的O(n log n)?