基数排序:不稳定的排序
基数排序(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; } }