`

位图排序

阅读更多

《编程珠玑》第一章第一题就相当的精彩,做个笔记。题目如下:
输入: 一个包含n个正整数的文件,每个正整数小于n,n等于10的7次方(一千万)。并且文件内的正整数没有重复和关联数据。

输出: 输入整数的升序排列

约束: 限制在1M内存,充足的磁盘空间

假设整数占32位,1M内存可以存储大概250000个整数,第一个方法就是采用基于磁盘的合并排序算法,第二个办法就是将0-9999999切割成40个区间,分40次扫描(10000000/250000),每次读入250000个在一个区间的整数,并在内存中使用快速排序。书中提出的第三个解决办法是采用bitmap(或者称为bit vector)来表示所有数据集合(注意到条件,数据没有重复),这样就可以一次性将数据读入内存,减少了扫描次数。算法的伪代码如下:
阶段1:初始化一个空集合
for i=[0,n)
bit[i]=0;
阶段2:读入数据i,并设置bit[i]=1
for each i in the input file
bit[i]=1;
阶段3:输出排序的结果
for i=[0,n)
if bit[i]==1
write i on the output file

这个算法的时间复杂度在O(n),用c语言写的版本可以在10秒内完成任务!c语言的源码在该书主页上有,这里给一个java的测试版,加上我的理解注释:

/**
 * Created by IntelliJ IDEA.
 * User: zhuangxd
 * Date: 2008-1-7
 * Time: 14:30:44
 */
public class BitSortTest {
    private static final int BITSPERWORD = 32;  //整数位数
    private static final int SHIFT = 5;
    private static final int MASK = 0x1F;  //5位遮蔽 0B11111
    private static final int N = 10000000;
    //用int数组来模拟位数组,总计(1 + N / BITSPERWORD)*BITSPERWORD位,足以容纳N
    private static int[] a = new int[(1 + N / BITSPERWORD)];

    public static void main(String[] args) {
        bitsort(new int[]{1, 100, 2, 10000, 9999, 4567, 78902});
    }

    public static void bitsort(int[] array) {
        for (int i = 0; i < N; i++)
            clr(i);   //位数组所有位清0
        for (int i = 0; i < array.length; i++)
            set(array[i]);   //阶段2
        for (int i = 0; i < N; i++)
            if (test(i))
                System.out.println(i);
    }

    //置a[i>>SHIFT]的第(i & MASK)位为1,也就是位数组的第i位为1
    public static void set(int i) {
        a[i >> SHIFT] |= (1 << (i & MASK));
    }

    //置a[i>>SHIFT]的第(i & MASK)位为0,也就是位数组的第i位为0
    public static void clr(int i) {
        a[i >> SHIFT] &= ~(1 << (i & MASK));
    }

    //测试位数组的第i位是否为1
    public static boolean test(int i) {
        return (a[i >> SHIFT] & (1 << (i & MASK))) == (1 << (i & MASK));
    }
}



 

 

 

分享到:
评论
4 楼 j_bird 2012-05-21  
你好,看了上面的代码个人有些疑问,想求教一下,主要疑问如下:
   
   1、a[i >> SHIFT] &= ~(1 << (i & MASK));  为什么要调用这段代码呢,申 明的整型数组默认值不都是0吗?
  2、i & MASK 为什么要做这步呢,直接用~(1 << i);是否可以呢?
  
  3、a[i >> SHIFT] &= ~(1 << (i & MASK)); 这样一位一位的清零快些还是以对数组的每个整型变量直接赋值0快些呢?
   还请赐教
3 楼 liuxuejin 2011-03-17  
不知道跟C的比起来,性能如何!
2 楼 fhtdy2004 2009-10-20  
//用int数组来模拟位数组,总计(1 + N / BITSPERWORD)*BITSPERWORD位,足以容纳N  
    private static int[] a = new int[(1 + N / BITSPERWORD)];  
请教一下,你开了一个312500个整数的数组,而1M只能存储250000个整数,这不是超过了内存的限制?
1 楼 txzyhm521 2008-03-26  
/** 
* Created by IntelliJ IDEA.
*/
破解的吧,告诉我版本和注册号

相关推荐

    位图排序《编程珠玑》

    实现位图排序,其中假设n为10 000 000,且输入文件包含1 000 000个正数;具体细节详见《编程珠玑》第一章问题; 由于数据的大小问题,在这#define N 1000,即数据在1000以内的100个数据,进行排序(当然由于随机数...

    PHP实现bitmap位图排序与求交集的方法

    本文实例讲述了PHP实现bitmap位图排序求交集的方法。分享给大家供大家参考,具体如下: 初始化一串全为0的二进制; 现有一串无序的整数数组; 如果整数x在这个整数数组当中,就将二进制串的第x位置为1; 然后顺序读取这...

    编程珠玑之位图排序

    输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7,。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该整数关联。 输出:按升序排列的输入整数列表。 约束:最多有(大约)1MB的...

    C++实现位图排序实例

    在《编程珠玑》一书里提到了一种算法导论里没有提到过的位图排序方法,这种排序方法是通过牺牲空间效率来追求时间效率(线性时间)以达到时间-空间折中与双赢的目的。本文以实例形式简单讲一下位图排序思想。 一、...

    位图数据结构在排序算法中的应用.pdf

    位图排序算法的优势在于其时间复杂度为O(n),在内存开销方面,位图排序只需要足够的位数来表示数据集合中所有可能的值。不过,这种方法在某些情况下仍然存在限制,例如当输入文件中的整数范围非常大时,可能需要超过...

    用位图排序无重复数据集实例代码(C++版)

    位图排序是一种特殊的排序算法,尤其适用于处理包含无重复元素的整数集合。该方法利用了计算机内存中的一位可以代表一个状态的事实,通常用于表示一个整数是否存在。位图排序的基本思想是创建一个与待排序数据最大值...

    个人针对学习几种排序算法的总结

    位图排序是一种使用位运算的高效排序方法,特别适合于排序那些可以表示为固定范围的整数数组。它通过建立一个位图,每一位对应一个数据值,然后依次检查每个数据值,并在位图上相应位置置为1,最终通过位图直接生成...

    你要找的这里~滴滴滴1

    【部分内容】:介绍了使用位图排序解决十亿个QQ号判断问题的思路与方法。 在Java面试中,位图排序是一种有效的数据处理策略,特别是在处理大量数据且内存有限的情况下。本例中,问题是如何在一个十亿个QQ号的列表中...

    Java 位图法排序的使用方法

    位图法排序是一种在特定情况下效率较高的排序技术,尤其适用于数据范围相对较小的整数排序。这种方法基于位操作,利用数组来表示一个位图,其中每一位对应一个可能的数值。在Java中,虽然标准库中的排序算法如`...

    点阵LCD液晶模块的实现方案

    位图必须是黑白单色并旋转270度,然后通过添加到下载位图排序中。连接模块和电脑后,选择正确的串口,使用“状态测试”检查连接,然后下载位图到模块的FLASH中。下载完成后,断电并切换模块至正常模式,再次上电,就...

    二分法排序算法 C语言实现

    根据给定的文件信息,我们可以总结出以下关于“二分法排序算法C语言实现”的相关知识点: ### 1. 二分法搜索算法原理 二分法搜索算法,也称为折半查找算法,是一种在有序数组中查找特定元素的搜索算法。其基本思想...

    c# 实现位图算法(BitMap)

    2. 不可对重复的数据进行排序和查找。 C# 中的 BitMap 实现 在 .NET 中已经实现了 BitMap 的数据结构——BitArray,我们可以直接使用官方的 BitArray 来解决问题。但是,我们也可以参照 .NET 源码实现一个简化版的...

    BMP位图转换AVI视频例程

    然后,这些帧按照特定的帧率进行排序和组合,形成连续的动态画面。 4. **编程实现**:通常,这个过程可以通过编程语言如C++、Python或Java来实现,利用图像处理库如OpenCV、FFmpeg等。例如,在OpenCV中,可以使用...

    mfc实现排序算法的动态演示 (源程序)

    `res`文件夹通常包含应用程序所需的资源,如位图、图标等,而`sortTest.dsw`是Visual Studio的工作空间文件,用于管理项目。 在MFC环境中,动态演示排序算法可能涉及到使用C++的绘图函数,如GDI(Graphics Device ...

    pb 点击标题排序 title order powerbuild9

    1. ORDERUP.BMP和ORDERDW.BMP:这可能是两个位图文件,分别表示升序和降序的图标。在PowerBuilder中,可以将这些图标设置到DataWindow的列标题上,以视觉上指示当前的排序状态。 2. DWSORT.PBL:这是一个Power...

    能够自动排序的源代码适合初学者下载

    - .BMP 文件是位图图像文件,通常用于存储项目中的图标或图片资源。 - .CFG 文件是配置文件,可能包含了项目的设置和编译选项。 - .DCU 文件是编译后的单元文件,包含了编译过的Pascal源代码,是DELPHI编译后生成的...

    寻找位图中出现频次最多的颜色

    在图像处理领域,有时我们需要分析位图(Bitmap)中的颜色分布,找出最常出现的颜色,这一过程称为“颜色直方图”分析。本主题将深入探讨如何使用不同的算法和技术来解决这个问题,包括位图的基本概念、颜色表示法、...

Global site tag (gtag.js) - Google Analytics