基数排序:不稳定的排序
基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
package test;
import java.util.ArrayList;
import java.util.Arrays;
/*
* 基数排序:
* 基数排序是根据待排序的各个位上的值来进行桶排序,通过多次分配和收集过程,实现排序过程。
* 以基数为10为例,待排序数组[145,452,23,2676,876,347].
* 首先创建10个桶,
* 在第一趟分配中,分别取得数组中各个元素的个位上的值[5,2,3,6,6,7],将其放入对应的桶中
* T[0] 0
* T[1] 0
* T[2] 1 452
* T[3] 1 23
* T[4] 0
* T[5] 1 145
* T[6] 2 2676 876
* T[7] 1 347
* T[8] 0
* T[9] 0
*
* 其中第一个数表示桶中有多少个元素,后面对应放有元素
* 接着按桶顺序进行收集,得到新的数组:[452,23,145,2676,876.347]
*
* 接下来按照各个元素的十位上的值来分配,[5,2,4,7,7,4]
* T[0] 0
* T[1] 0
* T[2] 1 23
* T[3] 0
* T[4] 2 145 347
* T[5] 1 452
* T[6] 0
* T[7] 2 2676 876
* T[8] 0
* T[9] 0
* 然后收集得到[23,145,347,452,2676,876]
* 继续百位上的分配收集,最后既可以得到相应的排好序的数组了
*/
public class RadixSort {
public static void main(String args[]) {
int a[] = new int[]{145,452,23,2676,876,346};
radixSort(a,a.length);
System.out.println(Arrays.toString(a));
}
//基数排序
static void radixSort(int a[], int len) {
//创建数组链表作容器,其元素也是数组链表作桶。
ArrayList<ArrayList<Integer>> arrs = new ArrayList<ArrayList<Integer>>();
//总共10个桶,用来存放元素
for(int i = 0; i< 10; i++) {
ArrayList<Integer> arr = new ArrayList<Integer>();
arrs.add(arr);
}
//从个位开始,逐一进行分配-收集过程
for(int pos = 0; pos < 32; pos++) {
//对数组中每个数进行分配过程,pos 表示处理为位(个、十、百。。。)
for(int i = 0; i < len; i++) {
//获得元素对应位置上的值
int k = getNum(a,pos,i);
//将其放入对应的桶中
arrs.get(k).add(a[i]);
}
//收集过程
int m = 0; //m标记新数组上的位置,从0 -> len-1
//收集10个桶中的元素
for(int j = 0; j < 10 && m < len; j++) {
//当桶中有元素时
if(arrs.get(j).size() > 0) {
//逐一取出桶中的元素,放进数组中
for(int n = 0; n < arrs.get(j).size(); n++) {
a[m++] = (Integer)arrs.get(j).get(n);
}
//注意:取完桶中的元素后,要清空桶中的元素。否则会影响下次分配
arrs.get(j).clear();
}
}
}
}
//获得元素对应位置pos上的值
static int getNum(int a[],int pos,int i) {
int num = 1;
for(int j = 0; j < pos - 1; j++) {
num *= 10;
}
return (a[i] / num) % 10;
}
}