周立功来讲解哈希表的实现
(struct _node_find_ctx *)p_arg; // 用户参数为寻找结点的上下文
12 char *p_mem = (char *)p_node + sizeof(slist_node_t); // 关键字存储在结点之后
13
14 if (memcmp(p_mem, p_info->key, p_info->key_len) == 0) {
15 p_info->p_result = p_node;
16 return -1; // 找到该结点,终止遍历
17 }
18 return 0;
19 }
2021 int hash_db_search(hash_db_t *p_hash, const void *key, void *value)
22 {
23 int idx = p_hash->pfn_hash(key); // 得到关键字对应的哈希表的索引
24 struct _node_find_ctx info = {key, p_hash->key_len, NULL}; // 设置遍历链表的上下文信息
25 slist_foreach(&p_hash->p_head[idx], __hash_db_node_find, &info); // 遍历,寻找关键字对应结点
2627 if (info.p_result != NULL) { // 找到对应结点, 将存储的记录值拷贝到用户提供的空间中
28 memcpy(value, (char *)info.p_result+sizeof(slist_node_t)+p_hash->key_len+p_hash->value_len);
29 return 0;
30 }
31 return -1;
32 }程序中,由于查找结点时需要遍历链表,关键字比对的操作需要在遍历函数的回调函数中完成,因此,需要将用户查找记录使用的关键字信息(关键字及其长度)提供给回调函数,同时,当查找到记录时,需要将查找到的结点反馈给调用遍历函数的主程序。为此,定义了一个内部使用的用于寻找一个结点的上下文结构体:
struct _node_find_ctx {
const void *key; // 查找关键字
unsigned int key_len; // 关键字长度
slist_node_t *p_result; // 用于存储查找到的结点
};调用遍历函数时,需要提供一个设置好关键字信息的结构体作为回调函数的用户参数。遍历函数结束时,可以通过该结构体中的p_result成员获取遍历结果。
4. 删除记录
该接口用于删除指定关键字对应的记录,可以定义其函数名为:hash_db_del()。删除记录时,需要指定关键字信息。可以定义函数的原型为:
int hash_db_del(hash_db_t *p_hash, const void *key);
以删除学号为201444700239的学生记录为例,使用范例如下:
unsigned char id[6] = {0x20, 0x14, 0x44, 0x70, 0x02, 0x39}; hash
- 电源软启动的实用设计技巧(07-16)
- 周立功:动态分布内存——malloc()函数与calloc()函数(07-22)
- 周立功“程序设计与数据结构”:深度解剖动态分布内存的free()函数与realloc()函数(07-25)
- 周立功教你学程序设计技术:做好软件模块的分层设计,回调函数要这样写(07-30)
- 周立功教你学C语言编程:教你数组是如何保存指针的(07-31)
- 算法的泛化问题,这些坑你可能都经历过!|周立功教你学软件设计(08-01)