基数排序 (LSD)
前置知识:计数排序
介绍
基数排序的复杂度是
其中
思想
基数排序(LSD)的思想是将所有整数高位补零,以个位、十位、百位、千位,依次为基准进行排序,通常使用计数排序来辅助。 当前位排序时,同一关键字的数据内部是从小到大排列的,因为在上一位排序时,我们已经将数列按照上一位为关键字从小到大排序,这保证了基数排序的正确性。
实现过程
粘一张来自 OI-wiki 的图片方便理解,具体实现在代码里。
P1177 AC CODE
#include <iostream>
using namespace std;
int a[100100], b[10][100100], cnt[10];
int main()
{
int n, x = 10;
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i <= 9; ++i) // 在本题中 k 的大小为 9 ,进行 9 轮排序
{
for (int j = 0; j <= 9; ++j) cnt[j] = 0;
// 每次排序前要将记录每个关键字数量的 cnt 数组清空
for (int j = 1; j <= n; ++j)
{
int de = (a[j] % x) / (x / 10); // 分离出关键字(0-9)
b[de][++cnt[de]] = a[j]; // 将每个关键字分到的数据记录
}
x = x * 10;
int tp = 0;
for (int j = 0; j <= 9; ++j) // 依据关键字顺序来进行排序
{
for (int k = 1; k <= cnt[j]; ++k)
{
a[++tp] = b[j][k]; // 将原数组覆盖为本轮排序后数组
}
}
}
for (int i = 1; i <= n; ++i) cout << a[i] << " ";
return 0;
}