用链表和数组实现HASH表,几种碰撞冲突解决方法
Hash算法中要解决一个碰撞冲突的办法,后文中描述了几种解决方法。下面代码中用的是链式地址法,就是用链表和数组实现HASH表。
he/*hash table max size*/ #define HASH_TABLE_MAX_SIZE 40/*hash table大小*/ int hash_table_size=0;/*.BH----------------------------------------------------------------- ** 结构体定义 **.EH----------------------------------------------------------------- */ /*hashTable结构*/ typedef int HashKeyType; typedef struct{ OMS_TYPE__CurrFaultReport curr_fault_report;unsigned int begin_time[SYS_FAULT_REPORT_MAX_NUM];unsigned int end_time[SYS_FAULT_REPORT_MAX_NUM];unsigned int report_valid[SYS_FAULT_REPORT_MAX_NUM]; }HashValueType;typedef struct HashNode_Struct HashNode; struct HashNode_Struct {HashKeyType sKey;HashValueType nValue;HashNode* pNext; }; HashNode* hashTable[HASH_TABLE_MAX_SIZE]; //hash table data strcutrue/*=================hash table function======================*/ /*.BH----------------------------------------------------------------- ** **函数名: ** **功能:string hash function ** **参数: 无 ** **返回值:无 ** **设计注记: ** **.EH----------------------------------------------------------------- */ unsigned int hash_table_hash_str(const char* skey) {const signed char *p = (const signed char*)skey;unsigned int h = *p;if(h){for(p += 1; *p != '\0'; ++p){h = (h << 5) - h + *p;}}return h; }/*.BH----------------------------------------------------------------- ** **函数名: ** **功能:insert key-value into hash table ** **参数: 无 ** **返回值:无 ** **设计注记: ** **.EH----------------------------------------------------------------- */ int hash_table_insert(const HashKeyType skey, HashValueType nvalue) {unsigned int pos = 0;HashNode* pHead = NULL;HashNode* pNewNode = NULL;if (hash_table_size >= HASH_TABLE_MAX_SIZE){printf("out of hash table memory!\n");return 0;}pos = hash_table_hash_str(skey) % HASH_TABLE_MAX_SIZE;pHead = hashTable[pos];while (pHead){if (pHead->sKey == skey){printf("hash_table_insert: key %d already exists!\n", skey);return 0;}pHead = pHead->pNext;}pNewNode = (HashNode*)malloc(sizeof(HashNode));memset(pNewNode, 0, sizeof(HashNode));pNewNode->sKey = skey;memcpy(&pNewNode->nValue, &nvalue, sizeof(HashValueType));pNewNode->pNext = hashTable[pos];hashTable[pos] = pNewNode;hash_table_size++;return 1; }/*.BH----------------------------------------------------------------- ** **函数名: ** **功能:lookup a key in the hash table ** **参数: 无 ** **返回值:无 ** **设计注记: ** **.EH----------------------------------------------------------------- */ HashNode* hash_table_find(const HashKeyType skey) {unsigned int pos = 0;pos = hash_table_hash_str(skey) % HASH_TABLE_MAX_SIZE;if (hashTable[pos]){HashNode* pHead = hashTable[pos];while (pHead){if (skey == pHead->sKey)return pHead;pHead = pHead->pNext;}}return NULL; }/*.BH----------------------------------------------------------------- ** **函数名: ** **功能:free the memory of the hash table ** **参数: 无 ** **返回值:无 ** **设计注记: ** **.EH----------------------------------------------------------------- */ void hash_table_release() {int i;for (i = 0; i < HASH_TABLE_MAX_SIZE; ++i){if (hashTable[i]){HashNode* pHead = hashTable[i];while (pHead){HashNode* pTemp = pHead;pHead = pHead->pNext;if (pTemp){free(pTemp);}}}} }//remove key-value frome the hash table /*.BH----------------------------------------------------------------- ** **函数名: ** **功能:string hash function ** **参数: 无 ** **返回值:无 ** **设计注记: ** **.EH----------------------------------------------------------------- */ void hash_table_remove(const HashKeyType skey) {unsigned int pos = hash_table_hash_str(skey) % HASH_TABLE_MAX_SIZE;if (hashTable[pos]){HashNode* pHead = hashTable[pos];HashNode* pLast = NULL;HashNode* pRemove = NULL;while (pHead){if (skey == pHead->sKey){pRemove = pHead;break;}pLast = pHead;pHead = pHead->pNext;}if (pRemove){if (pLast)pLast->pNext = pRemove->pNext;elsehashTable[pos] = NULL;free(pRemove);}}hash_table_size--; }/*.BH----------------------------------------------------------------- ** **函数名: ** **功能:print the content in the hash table ** **参数: 无 ** **返回值:无 ** **设计注记: ** **.EH----------------------------------------------------------------- */ void hash_table_print() {int i;printf("===========content of hash table===========\n");for (i = 0; i < HASH_TABLE_MAX_SIZE; ++i){if (hashTable[i]){HashNode* pHead = hashTable[i];printf("%d=>", i);while (pHead){printf("%d:%d ", pHead->sKey, pHead->nValue.begin_time);pHead = pHead->pNext;}printf("\n");}} }/*.BH----------------------------------------------------------------- ** **函数名: ** **功能:初始化系统名称的hashTable,插入所有系统名称 ** **参数: 无 ** **返回值:无 ** **设计注记: ** **.EH----------------------------------------------------------------- */ void Common_InitHashTable() {hash_table_size = 0;memset(hashTable, 0, sizeof(HashNode*) * HASH_TABLE_MAX_SIZE); }
Hash碰撞冲突
Hash函数的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰撞冲突。如下将介绍如何处理冲突,当然其前提是一致性hash。
1.开放地址法
开放地执法有一个公式:Hi=(H(key)+di) MOD m i=1,2,…,k(k<=m-1)
其中,m为哈希表的表长。di 是产生冲突的时候的增量序列。如果di值可能为1,2,3,…m-1,称线性探测再散列。
如果di取1,则每次冲突之后,向后移动1个位置.如果di取值可能为1,-1,2,-2,4,-4,9,-9,16,-16,…k*k,-k*k(k<=m/2),称二次探测再散列。
如果di取值可能为伪随机数列。称伪随机探测再散列。
2.再哈希法
当发生冲突时,使用第二个、第三个、哈希函数计算地址,直到无冲突时。缺点:计算时间增加。
比如上面第一次按照姓首字母进行哈希,如果产生冲突可以按照姓字母首字母第二位进行哈希,再冲突,第三位,直到不冲突为止
3.链地址法(拉链法)
将所有关键字为同义词的记录存储在同一线性链表中。如下:
因此这种方法,可以近似的认为是筒子里面套筒子
4.建立一个公共溢出区
假设哈希函数的值域为[0,m-1],则设向量HashTable[0..m-1]为基本表,另外设立存储空间向量OverTable[0..v]用以存储发生冲突的记录。
优缺点:
优点:
①拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
②由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
③开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
④在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表,删除结点不能简单地将被删结 点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是因为各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。因此在 用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。
缺点:
指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。
开放地址法和拉链法是比较常用的两种,各有优缺点,开放地址法的过程可以参考以下链接。
参考链接:HASH碰撞
转载于:https://www.cnblogs.com/AndrewYin/p/9203621.html
用链表和数组实现HASH表,几种碰撞冲突解决方法相关推荐
- 数据结构:哈希表函数构造和冲突解决方法
哈希表 哈希函数:记录的存储位置和它的关键字之间建立一个确定的对应关系. 冲突:对不同的关键字可能得到同一哈希地址,这种现象称为冲突. 哈希函数构造方法 1.直接定址法 取关键字或关键字的某个线性函数 ...
- 链表、数组、跳表时间复杂度
链表.数组.跳表时间复杂度 时间复杂度(流程决定) 何为常数时间的操作: 如果一个操作的执行时间不以具体样本呢量为转移,每次执行时间是固定时间,称这样的操作为常数时间的操作. 常见的常数时间操作: 常 ...
- 哈希表及哈希冲突解决办法
哈希表及哈希冲突解决办法 目录 什么是哈希表? 哈希表的数据结构 哈希冲突 哈希冲突解决办法 1. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直 ...
- Discuz支持反对提示:抱歉您的请求来路不正确或表单无法提交的解决方法
作者:admin 发布:2013-05-08 15:40 字符数:2947 分类:Discuz建站教程 阅读: 213 次 暂无评论 非一般感觉博客(www.zhukehua. ...
- 表单重复提交的解决方法
表单重复提交的解决方法 参考文章: (1)表单重复提交的解决方法 (2)https://www.cnblogs.com/lwj-0923/p/7367517.html 备忘一下.
- django.db.utils.OperationalError: (1050, “Table ‘表名‘ already exists)解决方法
django.db.utils.OperationalError: (1050, "Table '表名' already exists)解决方法 参考文章: (1)django.db.uti ...
- win7计算机管理打不开注册表,windows7系统下注册表打不开的解决方法
注册表是windows系统中的重要数据库,然而在使用windows7系统的时候我们经常会需要通过注册表来进行一些操作,可是有时候可能会遇到注册表打不开的情况,碰到这样的问题该如何解决呢?针对这个问题, ...
- SQL Sever2012 创建表时发生“未指定错误”解决方法
@[TOC]( SQL Sever2012 创建表时发生"未指定错误"解决方法 下载SQL2012,界面一般,而且从第二次使用时就发现,第一次创建的数据库都打不开,说是什么位置移动 ...
- 关于电源计划无法开启卓越模式/高性能模式,注册表无法找到CSEnabled的解决方法
关于电源计划无法开启卓越模式/高性能模式,注册表无法找到CSEnabled的解决方法 一.背景: 二.步骤(先看完): 三.原因: 一.背景: Windows系统版本号: 二.步骤(先看完): 关于开 ...
最新文章
- C#获得网络连接信息 IPGlobalProperties
- 科大星云诗社动态20210523
- 如何在Jupyter Notebook中使用在anaconda中创建的虚拟环境
- python3数据库框架_Python3 MySQL 数据库连接:安装pymysql(mysql数据库驱动), sqlalchemy(ORM框架)。...
- tensorflow CNN常用函数汇总
- selenium实现失败重运行
- 安装Numpy的简单方法
- 机器学习CS229极简的6张速查表
- 在线文本比较工具(用来对比两个代码文件差异的地方)
- 开发技巧--发送手机验证码接口调用
- 2022中国开发者影响力年度榜单揭晓,华为、阿里、腾讯等入选年度开源贡献企业 | 美通社头条...
- python实现——文件操作(超详细)
- android源码结构分析
- linux删除pdf密码
- Mysql中事务是什么?有什么用?
- Linux Shell 基础语法 流程控制 逻辑运算 字符串操作详细解析
- 世界历史50大著名统治者
- 上海高清卫星地图 百度卫星地图(含标签、道路信息、地名等数据叠加显示)
- 波斯顿房价 paddlepaddle 深度学习
- Netdiscover网络扫描工具
热门文章
- 全国计算机等级考试题库二级C操作题100套(第11套)
- oracle容错,Oracle DML容错处理方法
- 等压线上怎么画风向_战场上骑兵应该怎么拔刀?从清人佩刀为何总是刀柄向后说起...
- 操作系统:升级Windows 11正式版的四种方法,值得收藏!
- 网络安全:图片防盗链的实现原理
- svd奇异值分解_NCL专辑 | 奇异值分解(SVD)
- python基础(文件、异常、模块、类、对象)
- mrsql查询第二高的成绩_mysql-查找用户的最高分数和相关的详细信息
- linux查看运行钟的tomcat,linux查看tomcat启动运行日志
- hashmap 从头到尾_如何从头到尾设计一个简单的复古徽标