该算法也就是所谓的位图算法,用一个int表示32位,也就是实际值为1~32的数.
按照书里说的, 该算法只适合内存有限,而磁盘和时间不限,且数字在1~MAX之间不重复的排序.
1 package demo1; 2 3 /** 4 * Created with IntelliJ IDEA. 5 * User: wsyang 6 * Date: 13-11-3 7 * Time: 8:11 8 * To change this template use File | Settings | File Templates. 9 */ 10 public class BitSort { 11 12 public static void main(String[] args) { 13 //每个int类型数的位数(1个int数是4个字节,1个字节等于8位,所以是32=4*8) 14 int size = 32; 15 //最大值 16 int MAX= 10000000; 17 //计算出需要多大的数组,才能按位保存MAX个数.数组中每一个元素,也就是int数,能保存32位,所以是如下算数. 18 int arraySize = MAX/size + (MAX%size==0?0:1); 19 System.out.println("需要"+arraySize+"个数组元素"); 20 int[] datas = new int[arraySize]; 21 22 //测试数据 23 int[] orginal = new int[]{5,888,4,2,6,7,3,10,567,456,234,123,66666,55555,3333333,8908764}; 24 25 //完成位图的填充 26 for(int i=0;i<orginal.length;i++){ 27 int v = orginal[i];//原始值 28 //假设数值是33,因为1个int也就是32位只能表示1~32,因此,需要算出: 29 int index = v/size + (v%size==0?0:1)-1;//数组第几项才能表示目标数v 30 int pos = v % size - 1;//偏移量,也就是数组的index位置的int数的第几位才是这个数 31 //这里用了按位与运算,因为假设原值是000100,计算出偏移量是30,也就是说,倒数第二位是1,合并进去就是001 10. 32 //因此这里按位与运算最合适 33 int newResult = datas[index] | 1<< 31-pos;//新结果 34 //更新值 35 datas[index]=newResult; 36 System.out.print("原始值" + v); 37 System.out.print("下标" + index); 38 System.out.print("偏移" + pos); 39 System.out.print("新结果" + newResult); 40 System.out.println(); 41 } 42 //遍历位图,输出结果 43 for(int i=0;i<datas.length;i++){ 44 int data = datas[i]; 45 46 //有了data这个十进制数,如何得到她的二进制的每位值呢? 47 //很简单,需要得到某位的值,就将该数右移31-第几位,并将除末位外的所有位置为0,就能知道该位实际值. 48 for(int index=0;index<31;index++){ 49 //上条注释所言的计算方法 50 int posVal = (data >> (31-index)) & 1; 51 52 if(posVal==1){ 53 //如果该位是1,那么说明该位是有值的,输出她 54 //由于我们进行了拆分,也就是说当i=1时,基数是32开始,偏移量为1,就是33 55 int result = size*i + index+1; 56 System.out.print(result + ","); 57 } 58 } 59 60 } 61 } 62 }
这个程序的输出是:
需要312500个数组元素
原始值5下标0偏移4新结果134217728
原始值888下标27偏移23新结果256
原始值4下标0偏移3新结果402653184
原始值2下标0偏移1新结果1476395008
原始值6下标0偏移5新结果1543503872
原始值7下标0偏移6新结果1577058304
原始值3下标0偏移2新结果2113929216
原始值10下标0偏移9新结果2118123520
原始值567下标17偏移22新结果512
原始值456下标14偏移7新结果16777216
原始值234下标7偏移9新结果4194304
原始值123下标3偏移26新结果32
原始值66666下标2083偏移9新结果4194304
原始值55555下标1736偏移2新结果536870912
原始值3333333下标104166偏移20新结果2048
原始值8908764下标278398偏移27新结果16
2,3,4,5,6,7,10,123,234,456,567,888,55555,66666,3333333,8908764,
Process finished with exit code 0