问题:
输入:给出至多10,000,000个正整数的序列
特征:每个数都小于10,000,000、数据不重复 且 数据之间不存在关联关系(相互独立)
输出:增序输出序列
约束:内存容量1MB,磁盘空间充足,运行时间至多几分钟,10是最适宜的时间
分析:我们需要10,000,000个数表示10,000,000个位。1MB的包含8*1024*1024个位
则,所需要的内存容量为:10,000,000/(8*1024*1024) = 1.20MB
这里和要求的差不多,我们可以使用位图排序,之后再进行优化,使之在1MB内存上运行
思路:
/*第一步,初始化这个比特位集合中的所有位为0*/
for i = [0, 10,000,000)
bit[i] = 0
/*第二步,读入待排序的正整数*/
for each i in the input file
bit[i] = 1
/*第三步,输出排序结果*/
for i = [0, 10,000,000)
if bit[i] == 1
write i on the output file
程序
使用字节存储位向量
#include <iostream>
using namespace std;
const int BITRERBYTE = 8;//位向量使用字节存储存储
const int SHIFT = 3; //右移3位,相当于除去8
const int MASK = 0x7; //16进制下的7
const int MAXNUM = 10000000;//最大的数为1千万
const int NUMCOUNT = 5;//实际待排序的数个数
unsigned char bit[MAXNUM/BITRERBYTE + 1];//位向量
/*置0*/
void InitBit(int i)
{
bit[i>>SHIFT] &= ~(1 << (i&MASK));
}
/*置1*/
void SetBit(int i)
{
bit[i>>SHIFT] |= (1 << (i&MASK));
}
/*检查是否1*/
int TestBit(int i)
{
return bit[i>>SHIFT] & (1 << (i&MASK));
}
int main()
{
int arr[NUMCOUNT] = {3,2,5,4,9};
//关闭所有位
memset(bit,0,sizeof(bit));
//读入待排序的整数
for (int i = 0;i < NUMCOUNT;i++)
{
SetBit(arr[i]);
}
//输出数据
for (int i = 0;i < MAXNUM;i++)
{
if (TestBit(i))
{
cout<<i<<" ";
}
}
cout<<endl;
system("pause");
return 1;
}
使用整形存储位向量
#include <iostream>
using namespace std;
const int BITPERWORD = 32;//位容器使用整形数据存储
const int SHIFT = 5; //右移5位,相当于除去32
const int MASK = 0x1F; //16进制下的31
const int MAXNUM = 10000000;//最大的数为1千万
const int NUMCOUNT = 5;//实际待排序的数个数
int bit[MAXNUM/BITPERWORD+ 1];//位向量
/*置0*/
void InitBi