数据结构 查找 哈希表

哈希:从高维空间【信息量更大的空间】到低维空间【所能容纳信息量较少的空间】的映射(会发生冲突)

冲突处理方法:4种

结构定义:

size:数组大小

data_type:任意类型映射到整型

提供数组下标找值

时间复杂度O(1)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct HashTable{
	int *data, *flag;//data一片连续的存储区;flag用于记录改位置是否存储;
	int size;//hash表的大小;
	int count;//统计当前hash表存储元素的数量;
}HashTable;

HashTable *init(int n){
	HashTable *h = (HashTable *)malloc(sizeof(HashTable) * 1);
	h->data = (int *)malloc(sizeof(int) * n * 2);//表示hash表存储一半时应该退出;
	int size = 2 * n / 30 + 1;//整型是32位;
	h->flag = (int *)calloc(size, sizeof(int));
	h->size = n;
	h->count = 0;
	return h;
}

int hash_value(HashTable *h, int ind){//hash表中第ind位有没有元素;
	int x = ind / 30, y = ind % 30;//x:这个位置的信息在第n个整数进行记录;y:在这个整数的第几位进行记录;
	return h->flag[x] & (1 << y);//1左移y位表示这个位置是不是1;
}

int set_value(HashTable *h, int ind, int val){//将val值插入到ind位置中去;
	int x = ind / 30, y = ind % 30;
	h->data[ind] = val;
	h->flag[x] |= (1 << y);//每次插入值后更新flag;a |= b 表示a等于a或b;
	h->count++;//插入了一个值,count+1;
	return 1;
}

int hash_conflict(HashTable *h, int *ind, int val){
	int times = 0, temp_ind = *ind;//冲突次数,*ind作为传出参数;
	while(hash_value(h, temp_ind) && h->data[temp_ind] != val){//当hash表中有值,且这个值不是val时;
		temp_ind += (++times);//开放定值法解决冲突;
		temp_ind %= h->size;//如果超出范围则取%;
	}
	*ind = temp_ind;
	return times;
}	

int hash(HashTable *h, int x){//从整型到数组下标的映射;无论插入还是查找都用到hash函数;
	return (x + h->size) % h->size;//x是一个负值时,需要+p->size;负数取%还是负数;
}

int insert(HashTable *h, int val){
	if(h->count * 2 > h->size){//超出hash表的范围;
		return 0;
	}
	int ind = hash(h, val);//找到待插入的位置;
	hash_conflict(h, &ind, val);
	if(h->data[ind] == val) return 0;//最后找到的ind位置已经存放val不必插入;
	set_value(h, ind, val);//没有存放val,则插入进去;
	return 1;
}

int search(HashTable *h, int val){
	int ind = hash(h, val);
	hash_conflict(h, &ind, val);
	return hash_value(h, ind);//当跳出循环时,满足条件1有值则表明这个值是val,满足条件2则表明无值查找失败;
}

void clear(HashTable *h){
	if(h == NULL) return ;
	free(h->data);
	free(h);
	return ;
}

int main(){
	HashTable *hash_table = init(100);
	int op, val;
	while(~scanf("%d%d", &op, &val)){
		switch(op){
			case 1:
				insert(hash_table, val);
				break;
			case 2:
				printf("value = %d\tresult = %d\n", val, search(hash_table, val));
				break;
			default:
				fprintf(stderr,"error\n");
				break;
		}
	}
	return 0;
}

输出结果:

value = 1	result = 2
value = 1000000	result = 1
value = 65544	result = 0

猜你喜欢

转载自blog.csdn.net/qq_38362049/article/details/81080336