9、链式哈希表
来源:互联网 发布:域名属于知识产权吗 编辑:程序博客网 时间:2024/06/01 20:16
1、哈希表
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
映射函数叫做散列函数,存放记录的数组叫做散列表。
冲突问题:两个不同的键映射到同一个位置
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
2、链式哈希表
数组每个元素存放一个链表首地址,一个链表为一个桶。输入一个数据,函数h将其转化为整型数据k,根据k处理得到数组元素指向的桶,在桶(链表)中执行插入或删除操作。
对于一定数量的元素,桶的数量m决定每个桶的大概深度。桶少要存储所有数据则桶的深度大。若使用取余法作为哈希函数,那么m一般取不为2的幂的素数。
3、代码分析
(1)数据结构
//CHTbl是哈希表的整体属性typedef struct _CHTbl{ int size;//存入的数据个数 int buckets;//桶数 int (*h)(const void *data);//哈希函数,转换索引值 int (*match)(const void *key1, const void *key2); void (*destroy)(void *data); LIST_ATTRITIVE *table;//数组首地址,数组中每个元素是一个链表(桶)的整体属性}CHTbl;typedef struct _LIST_ATTRITIVE{ int size; void (*destroy)(void (*data)); LIST_ELEMENT *head; LIST_ELEMENT *tail;}LIST_ATTRITIVE; typedef struct _LIST_ELEMENT{ void *data; struct _LIST_ELEMENT *next;}LIST_ELEMENT;
(2)链式哈希表初始化:初始化CHTbl,为每个一级链表元素LIST_ATTRITIVE分配空间,CHTbl中数组table指向每个一级链表元素。
#include <stdio.h>#include <string.h>#include "chtbl.h"#include "../SingleLink/single_list.h"//确定桶数,初始化每个桶的链表, int chtbl_init(CHTbl *htbl, int bucket, int (*h)(const void *key), int (*match)(const void *key1, const void *key2), void (*destroy)(void *data)){ int i; //为数组每个元素指向的桶属性分配空间 ,该空间长期有效 if((htbl->table = (LIST_ATTRITIVE *)(malloc(bucket * sizeof(LIST_ATTRITIVE)))) == NULL) return -1; htbl->buckets = bucket; for(i = 0; i < bucket; i++) { list_init(&htbl->table[i], 0 , destroy, NULL, NULL); } htbl->h = h; htbl->match = match; htbl->destroy = destroy; htbl->size = 0; return 0;}void chtbl_destroy(CHTbl *htbl){ int i; for(i = 0; i < htbl->buckets; i++) { list_destroy(&htbl->table[i]); } free(htbl->table); memset(htbl, 0 sizeof(CHTbl)); return;}//插入元素,只需要找到桶,在链表尾部插入 int chtbl_insert(CHTbl *htbl, const void *data){ void *temp; int bucket, retval; temp = (void *)data; if(chtbl_lookup(htbl, &temp) == 0) return 1; //处理data得到该放入哪个桶 bucket = htbl->h(data) % htbl->buckets; //在该桶指向的链表的尾部插入 if((retval = list_ins_next(&htbl->table[bucket], NULL, data)) == 0) htbl->size++; return retval;}//删除元素, 要便利对应桶的链表找到该元素 int chtbl_remove(CHTbl *htbl, void **data){ LIST_ELEMENT *element, *prev; int bucket; bucket = htbl->h(*data) % htbl->buckets; prev = NULL; //遍历 桶指向的链表 for(element = htbl->table[bucket]->head; element != NULL; element = element->next) { if(htbl->match(*data, element->data)) { if(list_rem_next(&htbl->table[bucket], prev, data) == 0) { htbl->size--; return 0; } else { return -1; } } //prev是匹配之间那个为匹配的元素 prev = element; } return -1;}int chtbl_lookup(CHTbl *htbl, void **data){ LIST_ELEMENT *element; int bucket; bucket = htbl->h(*data) % htbl->buckets; for(element = htbl->table[bucket]->head; element != NULL; element = element->next) { if(htbl->match(*data, element->data)) { *data = element->data; return 0; } } return -1;}
阅读全文
0 0
- 9、链式哈希表
- 链式哈希表
- 链式哈希表
- 哈希表的链式存储
- 链式哈希表的实现
- PHP实现 拉链式哈希表
- 链式哈希表(Hash Table)--算法导论示例
- C++实现哈希表 HashMap冲突链式解决
- 10、链式哈希表的应用-符号表
- scala进阶9-链式操作内幕
- ThinkPHP5学习(9)数据库-事务,链式操作
- C 算法精介----哈希表->链式哈希表->分析与实现
- 小白书之移动小球哈希表的链式结构
- 线性表数据结构解读(六)链式哈希表结构-LinkedHashMap
- 【9-1-5】简单链表,链式存储
- 链式队列
- 链式队列
- 链式队列
- maven中手动将jar包安装进仓库的方法及问题
- “破局”——2017庆科信息IOT解决方案发布会
- JS实现导航栏项目自动切换标签样式
- [数论] 拓展欧几里得算法 (poj1061 青蛙的约会)
- Test-简单加个背景音乐试一下
- 9、链式哈希表
- leetcode--Minimum Path Sum
- Python入门记录
- 图解Spring AOP
- Javascript的event对象属性详解
- session原理以及安全性
- Android 连续按两次返回键退出程序
- Java
- 刷题——Saruman's Army POJ