该算法也就是所谓的位图算法,用一个int表示32位,也就是实际值为1~32的数.

按照书里说的, 该算法只适合内存有限,而磁盘和时间不限,且数字在1~MAX之间不重复的排序.

 package demo1;

 /**
* Created with IntelliJ IDEA.
* User: wsyang
* Date: 13-11-3
* Time: 8:11
* To change this template use File | Settings | File Templates.
*/
public class BitSort { public static void main(String[] args) {
//每个int类型数的位数(1个int数是4个字节,1个字节等于8位,所以是32=4*8)
int size = 32;
//最大值
int MAX= 10000000;
//计算出需要多大的数组,才能按位保存MAX个数.数组中每一个元素,也就是int数,能保存32位,所以是如下算数.
int arraySize = MAX/size + (MAX%size==0?0:1);
System.out.println("需要"+arraySize+"个数组元素");
int[] datas = new int[arraySize]; //测试数据
int[] orginal = new int[]{5,888,4,2,6,7,3,10,567,456,234,123,66666,55555,3333333,8908764}; //完成位图的填充
for(int i=0;i<orginal.length;i++){
int v = orginal[i];//原始值
//假设数值是33,因为1个int也就是32位只能表示1~32,因此,需要算出:
int index = v/size + (v%size==0?0:1)-1;//数组第几项才能表示目标数v
int pos = v % size - 1;//偏移量,也就是数组的index位置的int数的第几位才是这个数
//这里用了按位与运算,因为假设原值是000100,计算出偏移量是30,也就是说,倒数第二位是1,合并进去就是001 10.
//因此这里按位与运算最合适
int newResult = datas[index] | 1<< 31-pos;//新结果
//更新值
datas[index]=newResult;
System.out.print("原始值" + v);
System.out.print("下标" + index);
System.out.print("偏移" + pos);
System.out.print("新结果" + newResult);
System.out.println();
}
//遍历位图,输出结果
for(int i=0;i<datas.length;i++){
int data = datas[i]; //有了data这个十进制数,如何得到她的二进制的每位值呢?
//很简单,需要得到某位的值,就将该数右移31-第几位,并将除末位外的所有位置为0,就能知道该位实际值.
for(int index=0;index<31;index++){
//上条注释所言的计算方法
int posVal = (data >> (31-index)) & 1; if(posVal==1){
//如果该位是1,那么说明该位是有值的,输出她
//由于我们进行了拆分,也就是说当i=1时,基数是32开始,偏移量为1,就是33
int result = size*i + index+1;
System.out.print(result + ",");
}
} }
}
}

这个程序的输出是:

需要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

编程珠玑第一章的算法,Java实现,通俗易懂的更多相关文章

  1. [Java编程思想] 第一章 对象导论

    第一章 对象导论 "我们之所以将自然界分解,组织成各种概念,并按其含义分类,主要是因为我们是整个口语交流社会共同遵守的协定的参与者,这个协定以语言的形式固定下来--除非赞成这个协定中规定的有 ...

  2. <编程珠玑>笔记 (一) 问题-算法-数据结构

    1  精确描述问题 第一章强调的重点在于”精确的描述问题“,这是程序开发的第一步 -- "Problem definition" 1.1  Precise problem stat ...

  3. 《大道至简》第一章读后感(java语言伪代码)

    中秋放假之际读了建民老师介绍的<大道至简>的第一章,其中以愚公移山的故事形象的介绍向介绍编程的精义.愚公的出现要远远早于计算机发展的历史,甚至早于一些西方国家的文明史.但是,这个故事许是我 ...

  4. JavaScript DOM编程艺术第一章:JavaScript简史

    本系列的博客是由本人在阅读<JavaScript DOM编程艺术>一书过程中做的总结.前面的偏理论部分都是书中原话,觉得有必要记录下来,方便自己翻阅,也希望能为读到本博客的人提供一些帮助, ...

  5. [书籍翻译] 《JavaScript并发编程》第一章 JavaScript并发简介

    > 本文是我翻译<JavaScript Concurrency>书籍的第一章,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并 ...

  6. Book-编程珠玑-第一章

    第一章...二〇一六年十月二十五日 22:41:45 1MB存储空间里大约可以存143,000个号码; 如果每个号码都使用32位整数来表示的话,1MB存储空间里就可以存储250,000个号码; 看得迷 ...

  7. 第一章 大体知道java语法1----------能写java小算法

    很多人开始学习java时,都是抱着诸如<Thinking in java>.<疯狂java>等书籍,从前到后慢慢翻看,不管其内容重要与否,也不关心自己以后能否使用到.我的建议是 ...

  8. java多线程编程核心技术——第一章总结

    目录: 1.1进程.多线程的概念,及线程的优点 1.2多线程的使用 1.3currentThread()方法 1.4isAlive()方法 1.5sleep()方法 1.6getId()方法 1.7停 ...

  9. JAVA 编程思想第一章习题

    //: ch1.01/IntChar.java package object; import java.util.*; public class IntChar { int x; char y; pu ...

随机推荐

  1. HTML中JavaScript调用方法

    我在写web页面的时候,经常用js实现某些功能,我用的方法有两种: 1.点击调用JavaScript: <button onclick="loadXMLDoc()">b ...

  2. java web 怎么下载大文件(上百M)

    Java代码   ; ]; , )) != -) { , bytesRead); 13.               } 14.               toClient.write(buffer ...

  3. 构造函数new执行与直接执行的区别

    //创建一个Test构造 function Test(){ // new执行与直接执行 this的不同指向 this.init(); }; // this 指向 Test Test.prototype ...

  4. 将电脑信息上传到中国移动ONENET平台

    用两个小时做的 可以用在服务器远程运维等环境非常方便 需要源码的可以联系NBDX123

  5. POJ3273--Monthly Expense(Binary Search)

    Description Farmer John is an astounding accounting wizard and has realized he might run out of mone ...

  6. 第88讲:Scala中使用For表达式实现map、flatMap、filter

    今天我们来学习一下如何使用for表达式实现map.flatMap以及filter 首先,我们来看下map.map的功能是,传入一个list,通过一个函数f,将list中的元素A变成元素B的过程.最后得 ...

  7. js跳转页面方法实现汇总

    一.页面之间的跳转传参 1.在页面之间跳转的方式有两种: window.location.href=”test.html?num=10”   地址会改变参数也会被传递但是不会打开新窗口 window. ...

  8. js-实现搜狐列表

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  9. AngularJS 指令中的require

    require参数可以被设置为字符串或数组,字符串代表另外一个指令的名字.require会将控制器注入到其值所指定的指令中,并作为当前指令的链接函数的第四个参数.字符串或数组元素的值是会在当前指令的作 ...

  10. delphi CopyFileProgressBar 拷贝文件显示进度条

    CopyFileProgressBar(pwidechar(ListBox1.Items.Strings[I]),pwidechar(NewDir+'\'+ExtractFileName(ListBo ...