位图排序算法

问题描述:

•输入
–给出至多10,000,000个正整数的序列
•特征:
–每个数都小于10,000,000
–数据不重复且 数据之间不存在关联关系
•输出:增序输出序列
•约束:
–内存容量1MB
–磁盘空间充足
–运行时间至多几分钟---最好线性时间

 

解答:

首先回顾下计数排序:

•思想:
–根据待排序中最大的数,开辟一个数组,记录每个整数出现的次数
–遍历一遍待排序的数据(排序的过程)
–顺序输出结果
•要求
–必须提前知道待排序数的最大数
•缺点
–有些数没有出现过,仍要为其保留一个空间
–只能针对整数进行处理
•优点

线性的排序算法

 

位图排序:

•引入位图排序的原因
–对计数排序算法进行空间压缩
•思想
–采用一个二进制位对应一个整数
•前提
–要知道待排序数的最大数
•存储
•使用字符或整形都可以

 

具体思路:

 

•举例

–存储:位图使用字符数组存储
•unsigned char bit[2];
•可用字节有两个0、1字节,一个字节中有八位
•我们只能表示16个数(0~15)
–问题
•给出一个数,怎么判断其对应位图的位置
–步骤
•找到该数对应的字节 +再找到该数对应的位
–方法
•14对应的字节:14/8 = 1      
•14对应的位:第14%8位
•14是存储在第1个字节上的第6号位
•8是存储在第1个字节上的第0号位

 
•已知:我们已找到待处理数所在的字节和位
•问题:

怎么设置对应位为1或0,且不能影响其他位

•思路:对其所在字节整体进行&和 |操作
•置1:
–1、先找到其所在字节:bitmap[num>>3]
–2、要把num对应位设为1即可
•难点:
–只把对应位为1,同时不影响该字节中的其他位
•方法:
–我们可以利用一个新的字节
–把该字节上num对应的位设为1,其他全为0
–之后与其所在字节进行或操作

  1. 1<<(num & 0b111);// 1向左移动多少位  
 1<<(num & 0b111);// 1向左移动多少位


置1、置0的思想

•置1:

–让其对应的二进制位为1,其他为0,与其对应字节,进行或操作

•置0:

–让其对应的二进制位为0,其他为1,与其对应的字节,进行与操作

 

优化

•优化的原因
–我们需要10,000,000个数表示10,000,000个位
–1MB的包含8*1024*1024个位
–所需内存容量:10,000,000/(8*1024*1024) = 1.20MB
 
•假如严格限制为1MB,可以采用的策略:
–两次遍历待排序列
 
•两次遍历待排序序列
–思想:把数据分成两部分,分别执行位图排序
 
–具体思路:
•第一次对1- 5,000,000之间的数排序
•之后再对5,000,001 -10,000,000之间的数排序
–需要存储空间为:5,000,000/(8*1024*1024) = 0.596MB
–总体上消耗的空间为0.596MB。

 

位图排序使用范围及应用

•位图排序使用范围
–(1)非负整数
–(2)每个整数最多出现一次
–(3)最大整数小于N
–(4)整数之间相互独立
 
•相关应用
–位图法存数据
–使用位图法判断数是否存在重复
–给40亿个不重复的unsignedint的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中

 

在STL中,bitset实现了相同功能

 在STL中实现:

    1. #include <bitset>   
    2. #include <iostream>   
    3.   
    4. using namespace std;  
    5.   
    6. int main()  
    7. {  
    8.     const int numcount = 10;  
    9.     const int MAXNUM = 20;  
    10.     int arr[numcount] = {2,20,13,7,2,18,16,5,1,0};  
    11.       
    12.     bitset<MAXNUM+1> bitmap;  
    13.     //指定为置1   
    14.     for (int i=0; i<numcount; i++)  
    15.     {  
    16.         bitmap.set(arr[i]);  
    17.     }  
    18.     //输出排序结果;   
    19.     for (int i=0; i<MAXNUM; i++)  
    20.     {  
    21.         if (bitmap.test(i))  
    22.         {  
    23.             cout<<i<<" ";  
    24.         }  
    25.     }  
    26. }  
posted @ 2014-07-01 19:08  tt_tt--->  阅读(683)  评论(0编辑  收藏  举报