位图排序

位图法就是bitmap的缩写,所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的。

位图算法称的上是最简单的算法,只需要一个for循环就能够搞定排序和查找,但是同时它也是对待操作的数据要求最苛刻的 ,首先这些数据必须是正整数,其次要大致知道这些数据的范围,且有一定的聚集性。

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

位图法定义

编辑
例如,要判断一千万个人的状态,每个人只有两种状态:男人,女人,可以用0,1表示。那么就可以开一个int 数组,一个int有32个位,就可以表示32个人。操作的时候可以使用 位操作

位图法应用

一、给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中
申请512M的内存
一个bit位代表一个unsigned int值
读入40亿个数,设置相应的bit位
读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在
二、使用位图法判断整形数组是否存在重复
判断集合中存在重复是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,这时双重循环法就不可取了。
位图法比较适合于这种情况,它的做法是按照集合中最大元素max创建一个长度为max+1的新数组,然后再次扫描原数组,遇到几就给新数组的第几位置上1,如遇到 5就给新数组的第六个元素置1,这样下次再遇到5想置位时发现新数组的第六个元素已经是1了,这说明这次的数据肯定和以前的数据存在着重复。这种给新数组初始化时置零其后置一的做法类似于位图的处理方法故称位图法。它的运算次数最坏的情况为2N。如果已知数组的最大值即能事先给新数组定长的话效率还能提高一倍。
三、使用位图法进行整形数组排序
四、位图法存数据
因为需要用到位运算,所以位图法只适用于正整数的排序及查找.



相关位操作:与& , 或|, 异或^, 非!.
移位操作: << 左移,右移>>

方法介绍:
假设有数组 int array[5] = {2,5,3,6,1}
由于最大值为6,我们只需一个int 型变量作为位图便可将这些整数存放于位图之中。
int bitmap=0 ; (32 bits)
该位图能表示的整数范围为: 0-31

那么该如何在位图中存储数组元素的信息呢?
1. 首先我们将数组中的每个整数用另一种方式表示。将1(即0x0000 0001)左移a[i]位
2.然后将所得结果和bitmap进行或操作
3. 存储数组元素的时间复杂度为O(n),其中n为数组长度;

for (int i=0;i<5;i++)
bitmap = bitmap|(1<<a[i]);

e.g.:
当i=0时, 
bitmap的值为 0000 0000 0000 0000 0000 0000 0000 0100 
(第2位为1,表示数组中有数值为2的元素)
当数组中所有数均进行同样的操作后,
bitmap的值为 0000 0000 0000 0000 0000 0000 0110 1110

如何通过bitmap的值得到数组所含元素呢?
查看数值i 是否存储在bitmap中的方法:
for(int i=0;i< MAX_VALUE;i++)
{
if((bitmap>>i)&1)
     {
//value i  is in the array, order by asc 
cout<<i<<"exists in the array!" <<endl;
}
}

应用场景:1. 数组排序,将元素按照此方法存入位图中,再从位图中输出元素,即为升序排列的元素 时间复杂度为2O(N),其中N 为数组长度
2. 两数组求交集。用两位图,然后对两位图进行与运算,可得两数组的交集 


     
          

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
0; } ``` 程序运行时,会显示一个菜单,让用户选择不同的功能,例如: ``` 1位索引(Bitmap Index)是一种特殊类型的索引,它使用位存储数据。对于列中的每个不同值,位索引都会创建一个位,其中每个位对应于表中的. 添加学生信息 2. 显示所有学生信息 3. 按总分排序 4. 按DataStructure成绩排序一行。如果值出现在行中,则相应的位设置为1,否则为0。通过使用位索 5. 按C成绩排序 6. 查找某一C成绩的记录 0. 退出程序 请选择操作引,可以快速地定位符合特定查询条件的行。 位索引通常用于低基数(即不同值数量较少)列上,例如性别列等。在这种情况下,位索引可以(输入数字): ``` 用户可以根据需要选择不同的功能,程序会根据用户的选择执行相应极大地减少磁盘 I/O 操作,提高查询性能。但是,如果列具有高基数(即的操作,例如: ``` 请输入学号:001 请输入姓名:张三 请输入DataStructure成绩:90 请输入不同值数量较多),则位索引的效率可能会降低。 在 Oracle 数据库中,可以使用 CREATEC成绩:80 添加成功 请选择操作(输入数字):2 学号 姓名 DataStructure C 总分 BITMAP INDEX 语句创建位索引,例如: ``` CREATE BITMAP INDEX idx_gender ON employees(gender); ``` 001 张三 90.0 80.0 170.0 请选择操作(输入数字):3 按总这将在 employees 表的 gender 列上创建一个位索引。在查询中使用位索引时,可以使用 BIT分排序结果: 学号 姓名 DataStructure C 总分 001 张三 90.0 80.0 MAP AND、BITMAP OR、BITMAP NOT 等操作符组合多个位索引,以获得更高效的查询性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值