关于位图排序

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

输入:   一个包含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)

 

代码如下:

 

======================基于位图的整数序列合并算法=======================

搜索引擎检索时,常常要将两个结果进行组合处理,例如查询“中国北京”,则需要将包含“中国”和“北京”的文档编号序列进行合并的操作。常用的算法有归并,先排序后去重等,但这些算法在大数据量的情况下,如对包含“中国”的10万个文档编号序列和包含“北京”的8万个文档编号序列进行组合时,效率比较低,无法满足搜索引擎高速的检索要求。我们引入了基于二进制数组的算法来解决这个问题。
    基于二进制数组的整数序列合并算法是一种高速的多个整数序列组合的算法。它的基本原理是将各整数序列保存在一个二进制的数组当中,然后对这些二进制数组进行并,或的运算。
    下面详细介绍一下此算法的处理过程。
    1. 将整数序列转为二进制数组。
    先申请一个二进制数组,其大小为有可能出现的最大的整数值,如500万,如图所示。

(图1)

    假设有5个整数组成的序列{2,3,200,7000,12000},则我们可以将这个序列保存在二进制数组当中,如图2所示,第n位如果为1,则表示n存在于这个序列中:

(图2)

    2. 对两个序列进行位运算。
    如果需要对两个整数序列进行并的操作,那么只需要对它们对应的二进制数组进行“并”的位运算;如果需要对两个整数序列进行或的操作,那么只需要对它们对应的二进制数组进行“或”的位运算;如果需要对两个整数序列进行NOT的操作,那么只需要对它们对应的二进制数组先进行“并”的位运算,再进行“异或”的位运算。
    计算机进行位运算的速度是最快的。在实际的程序中,我们可以以long类型为基本的位运算单位,相同位置的long型数据进行两两位运算,以提高速度。
    3. 将二进制数组转为结果整数序列。
    位运算结束后,需要将这个结果再转为整数序列。这个转换后的整数序列就是我们需要的最终结果。
    下面是一次完整的运算过程,我们需要将{2,3,300}和{2,3,200,7000,12000}这两个序列进行并的操作。如图3所示。

(图3)

    整数序列{2,3}即是我们最终所要的结果。

海量数据排序:外部排序位图排序、基数排序、桶排序 基数排序又称桶排序,它不直接比较关键字的大小,而是比较关键字中各位的值来实现排序的。 假设关键字从高位到低位可以由k1、k2、……、kd构成。 最高位优先(MSD)法:先按k1排序分组,再对各组按k2排序分组,直到按最次位kd分组后,再将各组连接起来,便得到一个有序序列。 最低位优先(LSD)法:先从kd开始分组,再对kd-1进行排序,直到对k1分组后得到一个有序序列。 二进制快速排序 阅读详情

相关推荐

Java 位图排序的使用方法

本篇文章,小编将为大家介绍关于Java 位图排序的使用方法,有需要的朋友可以参考一下

排序8:位图排序

位图排序也称为bitmap排序,它主要用于海量数据去重和海量数据排序,假如说有10 亿个int类型且全部不相同的数据,给1G内存让你排序,你怎么排,如果全部加载到内 存中,相当于40亿个字节,大概约等于4G内存。所以全部加载到内存肯定不行,如果我 们使用位图排序的话,我们用long类型表示,一个long占用8个字节也就是64位,所以 如果我们使用位图排序的话只会占用约0.125G内存,内存占用大大减少。但位图排序有 个缺点就是数据不能有重复的,如果有重复的会覆盖掉,这也是位图能在海量数据中去 重的原因,我们

纵横千里 捭阖四方 的专栏 778

位图排序

《编程珠玑》第一章第一题就相当的精彩,做个笔记。题目如下:输入: 一个包含n个正整数文件每个正整数小于n,n等于107次方(一千万)。并且文件内的正整数没有重复和关联数据。输出: 输入整数的升序排列 约束: 限制在1M内存,充足的磁盘空间 假设整数占32位,1M内存可以存储大概250000个整数,第一个方法就是采用基于磁盘的合并排序算法,第二个办法就是将0-9999999...

庄周梦蝶 178

位图排序位图技术应用)

1.  问题描述          给定不大于整数 n 的 k 个互不相等的整数 ( k           2.  问题分析         关于排序,已经有多种排序方法了:插入排序,归并排序,快速排序,希尔排序等。每种排序都有不同的用武之地。为什么需要位图排序呢?所有的内部排序(上述所提及)都必须一次性将所有排序元素载入内存。假如有1000,000个整数,每个整数4字节,则意味着,至

瀞心:软件人生 3944

算法之美——位图排序

辉爷的高级数据结构开讲了,辉爷V5啊,今天辉爷讲的是位图排序。   问题描述: •输入 –给出至多10,000,000个正整数的序列 •特征: –每个数都小于10,000,000 –数据不重复且 数据之间不存在关联关系 •输出:增序输出序列 •约束: –内存容量1MB –磁盘空间充足 –运行时间至多几分钟---最好线性时间   解答: 首先回顾下计数排序: •思

小熊不去实验室 9041

位图排序 大数据_位图排序

应用位图排序引言生活中我们不可避免的会遇到大数据排序问题,这里是对《编程珠玑》中第1章中所描述的一类排序需求的简单手记。背景类似对存储7位电话号码的数据库进行整理,即对不超过一千万个不重复数据进行排序,限制内存占用1M和时间占用小于10s。预备时间对于一趟循环即时间复杂度为O(n)的程序需要至少一千万此操作,嵌套一层循环则为O(n^2),即一千万的平方次,显然是不现实的。所以最佳方案是一趟排序即...

weixin_39763953的博客 220

位图排序——编程珠玑

位图排序是一种效率极高(复杂度可达O(n))并且很节省空间的一种排序方法,但是这种排序方法对输入的数据是有比较严格的要求(数据不能重复,大致知道数据的范围)。位图排序即利用位图或者位向量来表示集合。举个例子,假如有一个集合{3,5,7,8,2,1},我们可以用一个8位的二进制向量set[1-8]来表示该集合,如果数据存在,则将set相对应的二进制位置1,否则置0.根据给出的集合得到的set为{1,

晴天的专栏 779

位图排序java,算法——Java版位图排序

前言最近在看编程珠玑,在第一章开篇中,作者通过一次友好的对话引出了位图排序,对话大致是某位程序员问题一个问题,“怎样给一个磁盘文件排序”前提输入:在一个最多包含n个正整数文件每个数都小于n,其中n=10^7。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该整数相关联。输出:按升序排列的输入整数的列表。约束:最多有(大约)1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最...

weixin_29865939的博客 238

C语言之位图排序

最近对于位运算特别感兴趣,是因为看到了一段C代码,只有短短一行就实现了令人咂舌的效果。代码如下: main(_){_^448&&main(-~_);putchar(--_%64?32|-~7[__TIME__-_/8%8][">'txiZ^(~z?"-48]>> ";;;====~$::199"[_*2&8|_/64]/(_&2?1:8)%8&1:10);} 输出结果是当前时间的特殊显示。

xulianghh的专栏 1186

位图排序法拓展: 可指定n趟的位图排序

可指定n趟的位图排序法,对之前位图排序的拓展。

猫晨的技术小屋 702
上一篇: 一种变进制数及其应用(全排列之Hash实现)
下一篇: 关于HadoopMapReduce的精彩介绍
inter999
博客等级 码龄19年 18粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值