基数排序:
Radix sort 是一种非比较型 整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
基数排序原理:
将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
基数排序结束条件:
第一个桶存满了,就表示排完了。
约定:
借助一个二维数组,二维数组的下标作为桶标识,一维数组(桶)的首元素作为该一维数组(桶)内存储了多少元素。
排序步骤演示:
dataset = [4, 13, 23, 10, 5, 11, 0, 27, 24, 18, 2, 16]
bucket[10][dataset.len+1]
对每个元素的最低位进行分割:int val = dataset[i] % 10
i | val | bucket[val] = dataset[i] |
0 | 4 | bucket[4] = [1,4] |
1 | 3 | bucket[3] = [1,13] |
2 | 3 | bucket[3] = [2,13,23] |
3 | 0 | bucket[0] = [1,0] |
4 | 5 | bucket[5] = [1,5] |
5 | 1 | bucket[1] = [1,11] |
6 | 0 | bucket[0] = [2,0,0] |
7 | 7 | bucket[7] = [1,27] |
8 | 4 | bucket[4] = [2,4,24] |
9 | 8 | bucket[8] = [1,18] |
10 | 2 | bucket[2] = [1,2] |
11 | 6 | bucket[6] = [1,16] |
从bucket[k range 0,10] 中 取出一维数组中的所有元素,并放回dataset
bucket[0] | [2,0,0] |
bucket[1] | [1,11] |
bucket[2] | [1,2] |
bucket[3] | [2,13,23] |
bucket[4] | [2,4,24] |
bucket[5] | [1,5] |
bucket[6] | [1,16] |
bucket[7] | [1,27] |
bucket[8] | [1,18] |
bucket[9] | [0] |
每个bucket 的首个元素都只代表这个bucket 中有多少个元素,不是用户数据,所以不要取错了。应该从第二个元素(下标1)开始取回元素
dataset = [0, 0, 11,2,13,23,4,24,5,16,27,18]
这是第一遍,下一边将 int val = dataset[i] % 10 改成取十位数字,如果高位没有数就填0
例如:4 没有十位,就改为04 % 100 / 10
直到第0 号桶填满为止。
/**
* 基数排序
*/
public class RadixSort {
public static void sort(int[] dataset){
// 定义一个临时存储的
int[][] radixBuckets = new int[10][dataset.length+1];
// 约定,每个 bucket 的第一个数据标识桶使用容量
int level = 1;
while (!firstBucketIsFull(radixBuckets)){
// 清空桶
for (int i = 0;i<radixBuckets.length;i++){
// 让桶尾指回即可。不是真正意义上的消除桶中数据。只是读不到了而已。
radixBuckets[i][0] = 0;
}
for (int i= 0;i<dataset.length;i++){
// 取出取出每轮对应的裁剪数
int dv =(dataset[i]/level) % 10;
// 桶尾
int end = radixBuckets[dv][0]+1;
// 从桶尾放入元素
radixBuckets[dv][end] = dataset[i];
// 桶尾 +1
radixBuckets[dv][0] = end;
}
// 将桶中数据写回 dataset
int index = 0;
for (int k = 0;k<radixBuckets.length;k++){
int[] bucket = radixBuckets[k];
for (int i = 1;i<=bucket[0];i++){
dataset[index++] = bucket[i];
}
}
level = level * 10;
}
}
static boolean firstBucketIsFull(int[][] radixBuckets){
if (radixBuckets[0][0] == radixBuckets[0].length-1){
return true;
}
return false;
}
}
以上智能排序正数,如果要排序据中有负数,可以再增加一个临时数组,里面是负数桶,最后合并两个临时数据就行了。