查找算法之巅-位图算法

 典型的用空间换时间的算法 哈希池(HashTable)也是如此

话不多说先来看看原理:用二进制来表示某个数是否存在,存在为1, 不存在为0

查找算法之巅-位图算法_第1张图片

 代码实现:

#include 
#include 
#include 

using namespace std;
// 这里我们进行初始化
// 初始化要很长的时间  这里是正常的 毕竟4000000000 个数据的查找
void 
init(char* str, int len)
{
	// num == 4000000000 左右多处几个字节这里不是重点
	unsigned int num = len * 8;
	char* ptr = str;
	for (unsigned int i = 0; i < num; i++) {
		if (i % 3 == 0) {
			ptr = str + i / 8; // 找到那个字节
			*ptr = *ptr | (1 << (i % 8)); // 通过位运算来吧那个位置为 1.
		}
	}
	return;
}

// 插入找函数
bool
find(char* str, int len, unsigned int value)
{
	if (value >= 8 * len) {
		return false;
	}

	char* tmp = str + value / 8; // 直接定位到那个字节
	// ret 不为 0 就存在返回true,否则返回false
	bool ret = *tmp & (1 << (value % 8));
	return ret;
}

int main(void)
{
	// 在40亿个数据中查找 某个数据是否存在,用for循环的话  你会被直接淘汰
	// int -21亿 ~ +21亿 不能用 int
	unsigned int num = 4000000000;
	/*
	if(num < 8){
		len == 0;所以这里要加 1 ,增强算法的健壮性
	}
	*/
	int len = num / 8 + 1;  // len = (5 0000 0000+1) 个字节 => 476 M 
	// 我8G的内存条 栈空间大概是 2M, 堆空间是 2G 左右 所以这里我们用堆

	char* str = (char*)calloc(len, sizeof(char)); // 全部初始化为 0
	if (!str) {// 由于分配的太多  防御性检查一下
		cerr << "内存分配失败!" << endl;
		system("pause");
		return 0;
	}

	init(str, len);

	// 我们写一个while循环来循环输入 看看是否 这种查找是否是在查找类算法的算法之巅
	time_t start, end;
	unsigned int value = 0;
	while (true) {
		cout << "请输入一个value进行查找.【如同想退出循环请输入 -1】" << endl;
		cin >> value;
		if (value == -1) {
			break;
		}
		time(&start);
		if (find(str, len, value)) {
			printf_s("%d 在值域中存在! \n", value);
		}else {
			printf_s("%d 在值域中不存在! \n", value);
		}
		time(&end);
		cout << "查找时间为:" << end - start << endl;
	}
	
	free(str);
	system("pause");
	return 0;
}

 效果演示:时间为0 表示没有超过1秒。

查找算法之巅-位图算法_第2张图片

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(c++)