位图:用一个bit来标记某个元素对应的值,键值就是该元素。最大的好处就是节省了内存空间。
应用场景:在海量数据中找出重复出现的元素或者去除重复出现的元素或者判断指定数是否在该海量数据中,例如,给40亿个未排序不重复的unsinged int的整数,判断某个数是否在这40亿的数据中,或者判断这40亿数据中哪些数是重复的。
基本原理:
1.给定数n,n所对应的字节位置:n/8;n所对应的位位置:n%8。例如数据12,12/8=1;12%8=4;即数据12对应的位在第一个字节的第四位上面,在该位上面置1
2.给定待排序的数组,对每个数据进行位的置1,同时建立一个temp数组,若某个数据出现了第二次,则temp数组对应位加1,即temp数组中的每个元素统计对应位置的重复出现个数。
3.排序时,按照从1开始到该数据的最大值进行循环,即从低位开始依次检查每一位,若给位为1则输出数据,即为排序后的数据,若为0则检查下一位。
代码:
#include <bitset>
using namespace std;
void BitSort(int list[], int n)
{
const int Max_Num = 20;
bitset<Max_Num + 1> bitmap;
int max = 0;
//找出待排序的数组中最大值
for (int i = 0; i < n; i++)
{
if (list[i] > max)
{
max = list[i];
}
}
int *temp = new int[max+1];
memset(temp, 0, sizeof(int)*(max + 1));
for (int i = 0; i < n; i++)
{
if (bitmap.test(list[i]))//若对应位为1则表示数有重复
{
temp[list[i]] += 1;//temp数组统计重复数字的个数
}
bitmap.set(list[i]); //将指定位置置1
}
int j=0;
for (int i = 0; i < Max_Num; i++)
{
if (bitmap.test(i))
{
list[j++] = i;
if (temp[i]>0)
{
list[j++] = i;
--temp[i];
}
}
}
}
时间复杂度: