1. 哈希表和哈希函数视频梗概
1.1. 文件描述
哈希表,Hash table,也称为散列表,它是可以根据关键字的值,直接进行查询与访问的数据结构。我们通常通过映射函数将关键字直接对应到表中的某个位置,从而加快查找速度。这个映射函数叫做哈希函数,存放记录的数组叫做哈希表。
1.2. 视频科普
2. 下标法:
建立一个指定长度的哈希表(哈希数组)
下标为哈希值,下标对应的元素值为这个哈希值出现了多少次,即有多少个关键字映射到了这个哈希值
如原数组A中有两个9,则哈希表table数组的table[9]的值为2
3. 哈希函数:
线性哈希函数,顾名思义,即关键字与哈希值是线性关系。用线性哈希函数可以完整记录原数据,可方便实现排序原数组的功能
整形取余表长,获得对应的哈希值
字符串的话把全部字符相加再取余表长得到相应的哈希值
4. uthash:
4.1. uthash适用范围:
uthash查找哈希表的时间复杂度都是常数级别的,但会受键数量和哈希函数的一些影响。但都远远高效于直接遍历全部键查找。
uthash中内置了几种不同的哈希函数,一般用默认的即可。
4.2. 可直接应用的哈希表插入、查找函数代码框架(使用中一般把uthash的函数进一步加工如下):
struct hashTable {
int key;
int val; //还可以时其他数据类型,例如数组等
UT_hash_handle hh; //uthash规定的哈希表处理句柄,把这个结构体标记为一个不在普通的结构体,而是哈希表操作的单位
};
/* 注意uthash里面的函数的参数一般都是指针*/
struct hashTable* hashtable; //uthash规定的哈希表头,或哈希表入口
//查找函数
struct hashTable* find(int ikey) {
struct hashTable* tmp; //用于操作(输出、插入)某一确定哈希结构体,
HASH_FIND_INT(hashtable, &ikey, tmp); //第一个为哈希表入口,第二个为要查找的键的地址,第三个为输出的哈希结构体(无则输出NULL)
return tmp;
}
//插入函数
void insert(int ikey, int ival) {
struct hashTable* it = find(ikey);
if (it == NULL) { //uthash不能对存在两个键相同的哈希结构体
struct hashTable* tmp = malloc(sizeof(struct hashTable)); //动态设置一个新的普通结构体(一对键值)
tmp->key = ikey, tmp->val = ival;
HASH_ADD_INT(hashtable, key, tmp); //将这个普通结构体转为哈希结构体第一个为哈希表入口,第二个为定义哈希结构体时定义的键名称,第三个为要插入的普通结构体(键值对)
} else {
it->val = ival; //覆盖原来相同键的哈希结构体
}
}