1、基数排序用于解决待排序记录数目较大,但记录关键字维数较小(如关键字是整数,则维数为10;若关键是字符串,则维数为26);
2、基数排序由分配和收集两部分组成;
3、基数排序实现的关键是下一趟的分配操作要在上一趟的收集结果上进行(分配和收集过程中均借助了单链表操作)。
4、关于基数排序算法代码说明如下:
(1)算法参数为包含有待排序数据的数组,其中数组元素结构如下:
class sort_element{
public int key;
public int next;
public sort_element(int key,int next){
this.key = key;
this.next = next;
}
@Override
public String toString(){
return String.valueOf(this.key);
}
}
(2)算法返回值为排好序的元素第一个;
(3)算法代码如下(代码中construct_chain()函数用于把数组构建成循环列表,其代码见(4), show_collection_result()函数用于显示算法执行过程中在收集阶段的收集结果,其代码见(5));
public static int radix_sort(sort_element [] arr_post_sort){
construct_chain(arr_post_sort);
int [] head = new int[10];
int [] tail = new int[10];
int M = 3;//关键字的最大位数
int bucket_number = -1;
int rg = 1;
int rd = 10;
int first_not_null_bucket_number = -1;//第一个非空桶编号
/**
* 下一次分配操作必须在上一次收集结果的基础上进行
* 这里first完成该功能,且first始终指向收集结果中的第一个元素
* */
int first = 0;
for(int i = 1; i <= M; i++){
//结束分配计数器
int end_count = 0;
//初始化桶
for(int j = 0; j < 10; j++){
head[j] = -1;
tail[j] = -1;
}
//开始分配
while(first >= 0){
end_count = end_count + 1;
bucket_number = (arr_post_sort[first].key / rg) % rd;
if(head[bucket_number] != -1){
arr_post_sort[tail[bucket_number]].next = first;
tail[bucket_number] = first;
}else{
head[bucket_number] = tail[bucket_number] = first;
}
first = arr_post_sort[first].next;
if(end_count >= 10)break;
}
//开始收集
//寻找第一个不为空的桶
int last = -1;//保存到目前为止收集到的最后一个元素编号
for(int n = 0; n < 10; n++){
if(head[n] != -1){
first = head[n];
last = tail[n];
first_not_null_bucket_number = n;//获得到第一个非空桶的编号
break;
}
}
//完成收集操作
for(int p = first_not_null_bucket_number + 1; p < 10; p++){
if(head[p] != -1){
arr_post_sort[last].next = head[p];
last = tail[p];
}
}
arr_post_sort[last].next = head[first_not_null_bucket_number];
//展示运行过程中每趟的收集结果
show_collection_result(head, first_not_null_bucket_number, arr_post_sort, i);
rg = rg * 10;
}
System.out.println();
return head[first_not_null_bucket_number];
}
(4)construct_chain()函数代码
public static void construct_chain(sort_element [] arr){
//construct chain and show it
System.out.print("建链后结果:" + " ");
for(int i = 0; i < arr.length - 1; ){
arr[i].next = ++i;
}
arr[arr.length - 1].next = 0;
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i].next + " ");
}
System.out.println();
}
(5)show_collection_result()函数代码
public static void show_collection_result(int [] head,
int first_not_null_bucket_number,
sort_element [] arr_post_sort, int round){
//展示运行过程中每趟的收集结果
int count = 1;
int index = head[first_not_null_bucket_number];
System.out.println();
System.out.print("第" + round + "趟收集" + " ");
while(count <= 10){
System.out.print(arr_post_sort[index].key + " ");
index = arr_post_sort[index].next;
count ++;
}
}
5、算法测试数据及测试方法
package ds_radix_sort;
public class ds_radix_sort {
public static void main(String[] args) {
//测试数据
sort_element [] target = new sort_element[]{
new sort_element(534, 0),new sort_element(2, 0),
new sort_element(0, 0),new sort_element(34, 0),
new sort_element(67, 0),new sort_element(13, 0),
new sort_element(111, 0),new sort_element(99, 0),
new sort_element(999, 0),new sort_element(235, 0),
};
//show pre sort_element
System.out.print("排序前状态:" + " ");
for(sort_element s : target){
System.out.print(s + " ");
}
System.out.println();
//do sort
int final_sort_first_element_index = radix_sort(target);
//show sort result
System.out.println();
System.out.print("排序后状态:" + " ");
int flag = 0;
int index = final_sort_first_element_index;
while(flag < 10){
System.out.print(target[index].key + " ");
index = target[index].next;
flag ++;
}
}
}
6、算法运行结果:
排序前状态: 534 2 0 34 67 13 111 99 999 235
建链后结果: 1 2 3 4 5 6 7 8 9 0
第1趟收集 0 111 2 13 534 34 235 67 99 999
第2趟收集 0 2 111 13 534 34 235 67 99 999
第3趟收集 0 2 13 34 67 99 111 235 534 999
排序后状态: 0 2 13 34 67 99 111 235 534 999
7、附录(程序完整代码)
package ds_radix_sort;
public class ds_radix_sort {
public static void main(String[] args) {
sort_element [] target = new sort_element[]{new sort_element(534, 0),new sort_element(2, 0),
new sort_element(0, 0),new sort_element(34, 0),
new sort_element(67, 0),new sort_element(13, 0),
new sort_element(111, 0),new sort_element(99, 0),
new sort_element(999, 0),new sort_element(235, 0),
};
//show pre sort_element
System.out.print("排序前状态:" + " ");
for(sort_element s : target){
System.out.print(s + " ");
}
System.out.println();
//do sort
int final_sort_first_element_index = radix_sort(target);
//show sort result
System.out.println();
System.out.print("排序后状态:" + " ");
int flag = 0;
int index = final_sort_first_element_index;
while(flag < 10){
System.out.print(target[index].key + " ");
index = target[index].next;
flag ++;
}
}
public static int radix_sort(sort_element [] arr_post_sort){
construct_chain(arr_post_sort);
int [] head = new int[10];
int [] tail = new int[10];
int M = 3;//关键字的最大位数
int bucket_number = -1;
int rg = 1;
int rd = 10;
int first_not_null_bucket_number = -1;//第一个非空桶编号
/**
* 下一次分配操作必须在上一次收集结果的基础上进行
* 这里first完成该功能,first始终指向收集结果中的第一个元素
* */
int first = 0;
for(int i = 1; i <= M; i++){
//结束分配计数器
int end_count = 0;
//初始化桶
for(int j = 0; j < 10; j++){
head[j] = -1;
tail[j] = -1;
}
//开始分配
while(first >= 0){
end_count = end_count + 1;
bucket_number = (arr_post_sort[first].key / rg) % rd;
if(head[bucket_number] != -1){
arr_post_sort[tail[bucket_number]].next = first;
tail[bucket_number] = first;
}else{
head[bucket_number] = tail[bucket_number] = first;
}
first = arr_post_sort[first].next;
if(end_count >= 10)break;
}
//开始收集
//寻找第一个不为空的桶
int last = -1;//保存到目前为止收集到的最后一个元素编号
for(int n = 0; n < 10; n++){
if(head[n] != -1){
first = head[n];
last = tail[n];
first_not_null_bucket_number = n;//获得到第一个非空桶的编号
break;
}
}
//完成收集操作
for(int p = first_not_null_bucket_number + 1; p < 10; p++){
if(head[p] != -1){
arr_post_sort[last].next = head[p];
last = tail[p];
}
}
arr_post_sort[last].next = head[first_not_null_bucket_number];
//展示运行过程中每趟的收集结果
show_collection_result(head, first_not_null_bucket_number, arr_post_sort, i);
rg = rg * 10;
}
System.out.println();
return head[first_not_null_bucket_number];
}
public static void show_collection_result(int [] head, int first_not_null_bucket_number, sort_element [] arr_post_sort, int round){
//展示运行过程中每趟的收集结果
int count = 1;
int index = head[first_not_null_bucket_number];
System.out.println();
System.out.print("第" + round + "趟收集" + " ");
while(count <= 10){
System.out.print(arr_post_sort[index].key + " ");
index = arr_post_sort[index].next;
count ++;
}
}
public static void construct_chain(sort_element [] arr){
//construct chain and show it
System.out.print("建链后结果:" + " ");
for(int i = 0; i < arr.length - 1; ){
arr[i].next = ++i;
}
arr[arr.length - 1].next = 0;
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i].next + " ");
}
System.out.println();
}
}
class sort_element{
public int key;
public int next;
public sort_element(int key,int next){
this.key = key;
this.next = next;
}
@Override
public String toString(){
return String.valueOf(this.key);
}
}