MSD 高位优先字符串排序 c++实现
变量解释:
s: 待排序的输入字符串的数组
t:用于排序的辅助数组
cnt :用于计数排序的计数器数组
lr: 当前正在排序的子数组的左端点和右端点
d: 正在排序的当前字符位置(从最重要的数字开始)
msd_sort函数: 通过对位置d处每个字符的频率进行计数,计算计数的累积和,并使用计数排序算法根据字符串的第d个字符对字符串进行排序,对当前子数组递归执行msd算法。然后递归地对每个字符的范围形成的子数组进行排序,直到子数组被完全排序。
主函数:读入输入字符串,调用msd_sort对其进行排序,并打印出排序后的字符串。
代码:
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1000005; // 最大字符串数
const int MAXL = 1005; // 字符串的最大长度
char s[MAXN][MAXL]; // 输入字符串
char t[MAXN][MAXL]; // 排序辅助数组
int cnt[256]; // 用于计数排序的计数器数组
void msd_sort(int l, int r, int d) {
if (l >= r || d < 0) return;
// 计算位置d处每个字符的频率
memset(cnt, 0, sizeof(cnt));
for (int i = l; i <= r; ++i) {
++cnt[(unsigned char)s[i][d]];
}
// 计算计数的累计和
for (int i = 1; i < 256; ++i) {
cnt[i] += cnt[i-1];
}
// 根据字符串的第d个字符对字符串进行排序
for (int i = r; i >= l; --i) {
int j = cnt[(unsigned char)s[i][d]]--;
strcpy(t[j], s[i]);
}
// 将排序后的字符串复制回输入数组
for (int i = l, j = 1; i <= r; ++i, ++j) {
strcpy(s[i], t[j]);
}
// 递归排序子数组
int p = l;
for (int i = 0; i < 256; ++i) {
int q = cnt[i];
msd_sort(p, q-1, d+1);
p = q;
}
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> s[i];
}
msd_sort(0, n-1, 0);
for (int i = 0; i < n; ++i) {
cout << s[i] << endl;
}
return 0;
}