引用资料
[1] algs4 MSD.java 完整代码实现
http://algs4.cs.princeton.edu/51radix/MSD.java.html[2] 搭建java环境 以及安装algs4程序(win版本,其余可参考官网for students部分)
http://algs4.cs.princeton.edu/windows/
说明
MSD
- 高位优先的字符串排序(most significant digit first) :
- 从左往右,递归排序;
- 适合于字符串长度不一的情况;
- 出现大量重复的字符串是最坏;
字母表 基数R
- 选用一个
R=26
的字母表 , 涵盖小写字母(这个选择会影响后面代码写下标); - 注意这个说法索引值,和后面的数组下标是 不同 的,这个代码容易出错就是下标和索引值的对应关系没搞明白;
索引值 | 字母 |
---|---|
0 | a |
1 | b |
…. … | |
18 | s |
19 | t |
…. … | |
25 | z |
待排序的字符串
she
sells
seashells
by
the
sea
shore
the
shells
she
sells
are
surely
seashells
逐行代码解释
代码的大框架
- ★ 标记的注释是需要仔细区分的盲点;
// 算法启动
public static void sort(String[] a) {
// 输入一个字符串数组 a 获取字符串数组的长度(即待排序的字符串个数)
int n = a.length;
// 声明一个备用字符串数组aux 用于排序时回写
String[] aux = new String[n];
// 启动递归排序 初始排序长度涵盖全部字符串[0,n-1]
// aux作为参数传入,相当于一个全局变量,aux只声明了一次 ★
sort(a, 0, n-1, 0, aux);
}
// 将字符串数组从 [lo,hi]的元素a[i] 按照 第d个字母 排序
private static void sort(String[] a, int lo, int hi, int d, String[] aux) {
// 函数局部变量,每次sort 都会重新创建一个count[]数组 ★
// 注意cout[]的长度为R+2 ★
int[] count = new int[R+2];
// 计算频率
for (int i = lo; i <= hi; i++) { }
// 频率转换成索引
for (int r = 0; r < R+1; r++) { }
// 数据分布
for (int i = lo; i <= hi; i++) { }
// 回写
for (int i = lo; i <= hi; i++) { }
// 递归排序
for (int r = 0; r < R; r++) { }
}
频率计算
MSD
// 频率计算
int[] count = new int[R+2];
for (int i = lo; i <= hi; i++) {
int c = charAt(a[i], d);
count[c+2]++;
}
解释
// 频率计算
// 1. count数组的作用是记录每个字母出现的频率(就是出现次数)
// 2. 把长度声明成 R+2 ;
// R 个位置用来放对应字母的出现次数
// 1 个位置用来应对达到字符串结尾
// 1 个位置是用于后面转化为索引 ★(下个标题说明)
int[] count = new int[R+2];
// for是一个从lo到hi的循环,就是遍历要排序的那些字符串,可能这一波排这5个字符串,
// 可能这一波排那3个字符串,实现只关注 子字符串数组 的效果;
for (