用bit map进行数组排序

504 篇文章 0 订阅
//定义每个Byte中有8个Bit位
#include <memory.h>
#define BYTESIZE 8
void SetBit(char *p, int posi)
{
	for(int i=0; i < (posi/BYTESIZE); i++)
	{
		p++;
	}

	*p = *p|(0x01<<(posi%BYTESIZE));//将该Bit位赋值1
	return;
}

void BitMapSortDemo()
{
	//为了简单起见,我们不考虑负数
	int num[] = {3,5,2,10,6,12,8,14,9};

	//BufferLen这个值是根据待排序的数据中最大值确定的
	//待排序中的最大值是14,因此只需要2个Bytes(16个Bit)
	//就可以了。
	const int BufferLen = 2;
	char *pBuffer = new char[BufferLen];

	//要将所有的Bit位置为0,否则结果不可预知。
	memset(pBuffer,0,BufferLen);
	for(int i=0;i<9;i++)
	{
		//首先将相应Bit位上置为1
		SetBit(pBuffer,num[i]);
	}

	//输出排序结果
	for(int i=0;i<BufferLen;i++)//每次处理一个字节(Byte)
	{
		for(int j=0;j<BYTESIZE;j++)//处理该字节中的每个Bit位
		{
			//判断该位上是否是1,进行输出,这里的判断比较笨。
			//首先得到该第j位的掩码(0x01<<j),将内存区中的
			//位和此掩码作与操作。最后判断掩码是否和处理后的
			//结果相同
			if((*pBuffer&(0x01<<j)) == (0x01<<j))
			{
				printf("%d ",i*BYTESIZE + j);
			}
		}
		pBuffer++;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	BitMapSortDemo();
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是基于散列表技术的排序的C++代码实现: ```cpp #include <iostream> #include <fstream> #include <bitset> #include <algorithm> #include <vector> #include <thread> using namespace std; const int MAX_NUM = 10000000; // 散列表的最大长度 const int BUCKET_SIZE = 100000; // 散列表的桶的数量 const int BUFFER_SIZE = 1000000000; // 缓冲区的大小,单位为字节 const int THREAD_NUM = 4; // 线程数量 bitset<MAX_NUM> bit_map; // 位图,用于判断某个数是否出现过 vector<int> bucket[BUCKET_SIZE]; // 散列表,每个桶存放一组数 char buffer[BUFFER_SIZE]; // 缓冲区,用于缓存内存中的数据 int buffer_pos = 0; // 缓冲区的当前位置 int last_num = 0; // 上一个读入的数 // 将一个数插入到散列表中 void insert_num(int num) { int pos = num % BUCKET_SIZE; // 计算桶的位置 bucket[pos].push_back(num); // 将数插入到桶中 bit_map.set(num, true); // 将位图相应位置设为true } // 将散列表中的数据写入缓冲区中 void write_bucket_to_buffer() { for (int i = 0; i < BUCKET_SIZE; i++) { if (bucket[i].size() > 0) { int len = bucket[i].size(); char* data = reinterpret_cast<char*>(&bucket[i][0]); // 将vector中的数据转换为char数组 int size = len * sizeof(int); // 计算数据大小 memcpy(buffer + buffer_pos, data, size); // 将数据复制到缓冲区中 buffer_pos += size; // 更新缓冲区的当前位置 bucket[i].clear(); // 清空桶中的数据 } } } // 排序线程函数 void sort_thread(int start, int end) { for (int i = start; i < end; i++) { int pos = i % BUCKET_SIZE; sort(bucket[pos].begin(), bucket[pos].end()); // 对桶中的数据进行排序 } } // 将缓冲区中的数据写入硬盘中 void write_buffer_to_disk(int file_num) { char file_name[20]; sprintf(file_name, "file_%d.bin", file_num); // 文件名为file_{file_num}.bin ofstream out(file_name, ios::binary); out.write(buffer, buffer_pos); // 将缓冲区中的数据写入文件中 buffer_pos = 0; // 清空缓冲区 } // 处理文件中的数据 void process_file(const char* file_name) { ifstream in(file_name, ios::binary); while (in.peek() != EOF) { int num; in.read(reinterpret_cast<char*>(&num), sizeof(int)); // 从文件中读入一个数 if (!bit_map.test(num)) { // 如果这个数没有出现过,则插入到散列表中 insert_num(num); } if (buffer_pos >= BUFFER_SIZE) { // 如果缓冲区已经满了,则将散列表中的数据写入缓冲区中 write_bucket_to_buffer(); if (buffer_pos >= BUFFER_SIZE) { // 如果散列表中的数据写入缓冲区后仍然超过了缓冲区的大小,则写入硬盘中 write_buffer_to_disk(last_num / MAX_NUM); last_num += MAX_NUM; } } } write_bucket_to_buffer(); // 处理完文件中的所有数据后,将散列表中的数据写入缓冲区中 } // 读入一个文件,并将其中的数据插入到散列表中 void read_file(const char* file_name) { thread t[THREAD_NUM]; for (int i = 0; i < THREAD_NUM; i++) { int start = i * MAX_NUM / THREAD_NUM; int end = (i + 1) * MAX_NUM / THREAD_NUM; t[i] = thread(sort_thread, start, end); // 创建排序线程 } process_file(file_name); // 处理文件中的数据 for (int i = 0; i < THREAD_NUM; i++) { t[i].join(); // 等待排序线程结束 } write_buffer_to_disk(last_num / MAX_NUM); // 将缓冲区中的数据写入硬盘中 } // 合并多个文件中的数据,并将结果写入到输出文件中 void merge_files(const char* output_file) { ofstream out(output_file, ios::binary); int file_num = (last_num / MAX_NUM) + 1; vector<ifstream> files(file_num); vector<int> nums(file_num); for (int i = 0; i < file_num; i++) { char file_name[20]; sprintf(file_name, "file_%d.bin", i); // 文件名为file_{i}.bin files[i].open(file_name, ios::binary); files[i].read(reinterpret_cast<char*>(&nums[i]), sizeof(int)); // 从文件中读入一个数 } while (true) { int min_num = MAX_NUM + 1; int min_pos = -1; for (int i = 0; i < file_num; i++) { if (nums[i] < min_num) { // 找到最小的数 min_num = nums[i]; min_pos = i; } } if (min_pos == -1) { // 如果没有找到最小的数,则退出循环 break; } out.write(reinterpret_cast<char*>(&min_num), sizeof(int)); // 将最小的数写入输出文件中 files[min_pos].read(reinterpret_cast<char*>(&nums[min_pos]), sizeof(int)); // 从文件中读入一个数 if (files[min_pos].peek() == EOF) { // 如果该文件已经读完,则关闭文件 files[min_pos].close(); } } } int main() { const char* input_file = "input.bin"; const char* output_file = "output.bin"; read_file(input_file); // 读入输入文件,并将其中的数据插入到散列表中 merge_files(output_file); // 合并多个文件中的数据,并将结果写入到输出文件中 return 0; } ``` 上述代码实现了将输入文件中的数据插入到散列表中,并将散列表中的数据排序后写入到缓冲区中,当缓冲区满了之后再将缓冲区中的数据写入到硬盘中。当处理完输入文件中的所有数据后,将散列表中的数据写入到缓冲区中,并将缓冲区中的数据写入到硬盘中。最后,将多个文件中的数据合并,得到最终的排序结果。在将散列表中的数据写入到硬盘中时,可以采用多线程并发的方式对每个桶进行排序,提高排序的效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值