哈希:从高维空间【信息量更大的空间】到低维空间【所能容纳信息量较少的空间】的映射(会发生冲突)
冲突处理方法: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