1. 哈希表的概念
   对于动态查找表而言,1) 表长不确定;2)在设计查找表时,只知道关键字所属范围,而不知道确切的关键字。因此,一般情况需建立一个函数关系,以f(key)作为关键字为key的录在表中的位置,通常称这个函数f(key)为哈希函数。(注意:这个函数并不一定是数学函数)

 1. 哈希函数是一个映象,即:将关键字的集合映射到某个地址集合上,它的设置很灵活,只要这个地址集合的大小不超出允许范围即可;
 2. 由于哈希函数是一个压缩映象,因此,在一般情况下,很容易产生“冲突”现象,即:key1 key2,而 f(key1) = f(key2) 并且,改进哈希函数只能减少冲突,而不能避免冲突。
      因此,在设计哈希函数时,一方面要考虑选择一个“好”的哈希函数;另一方面要选择一种处理冲突的方法。所谓“好”的哈希函数,指的是对于集合中的任意一个关键字,经哈希函数“映象”到地址集合中任何一个地址的概率是相同的,称这类哈希函数为“均匀的”哈希函数。
  根据设定的哈希函数H(key)和所选中的处理冲突的方法,将一组关键字映象到一个有限的地址连续的地址集(区间)上,并以关键字在地址集中的“象”作为相应记录在表中的存储位置,这种表被称为哈希表。哈希表是基于哈希函数建立的一种查找表。

2. 哈希函数的构造方法

  对数字的关键字可有下列哈希函数的构造方法,若是非数字关键字,则需先对其进行数字化处理。
(1) 直接定址法
  哈希函数为关键字的线性函数:
   H(key) = key 或者 H(key) = a key + b
  适用场合:地址集合的大小 = 关键字集合的大小 
(2)数字分析法
  假设关键字集合中的每个关键字都是由s位数字组成(k1, k2, …, kn),分析关键字集中的
  全体,并从中提取分布均匀的若干位或它们的组合作为地址。
  适用场合:能预先估计出全体关键字的每一位上各种数字出现的频度。
(3) 平方取中法
  若关键字的每一位都有某些数字重复出现频度很高的现象,则先求关键字的平方值,以通过
  “平方”扩大差别,同时平方值的中间几位受到整个关键字中各位的影响;
(4) 折叠法
  若关键字的位数特别多,则可将其分割成几部分,然后取它们的叠加和为哈希地址。可有
  
移位叠加间界叠加两种处理方法。
(5) 除留余数法
   H(key) = key MOD p p≤m (表长)
  关键问题是:如何选取 p ?
  p 应为不大于m 的质数或是不含20以下的质因子
  例如:key = 12, 39, 18, 24, 33, 21 时, 若取 p=9, 则使所有含质因子3的关键字均映射
     到地址0, 3, 6 上,从而增加了“冲突”的可能性。
(6) 随机数法
  H(key) = Random(key)实际造表时,采用何种构造哈希函数的方法取决于建表的关键字集合
   的情况(包括关键字的范围和形态),总的原则是使产生冲突的可能性降到尽可能地小。

3. 处理冲突的方法
  处理冲突的实际含义是:为产生冲突的地址寻找下一个哈希地址。
(1)开放定址法
  为产生冲突的地址H(key)求得一个地址序列:
  H0, H1, H2, …, Hs 1≤s≤m-1
  其中:H0 = H(key)
  Hi = ( H(key) + di ) MOD m i=1, 2, …,s
  增量 di 有三种取法:
  1) 线性探测再散列
   di = c i 最简单的情况 c=1
  2) 平方探测再散列
   di = 1², -1², 2², -2², …,
  3) 随机探测再散列
   di 是一组伪随机数列
   注意:增量di应具有“完备性”,即产生的Hi均不相同,且所产生的s(m-1)个Hi值能覆盖
       哈希表中所有的地址。要求:
   · 平方探测时的表长m必为4j+3的质数;
   · 随机探测时的m和di没有公因子。
(2)链地址法
   将所有哈希地址相同的记录都链接在同一链表中。
   线性探测容易产生二次聚集,链地址肯定不会产生二次聚集。一次聚集的产生主要取决于哈希函数,在哈希函数均匀的前提下,可以认为没有一次聚集。 

(3)再哈希法

在同义词产生地址冲突时计算另一个哈希函数地址,直到冲突不再发生。这种方法不易产生“聚集”,但增加了计算时间。

4. 哈希表的查找

  查找过程和造表过程一致。假设采用开放定址处理冲突,则查找过程为:
  对于给定值K, 计算哈希地址 i = H(K) ,若r[i] = NULL 则查找不成功;
  若 r[i].key = K 则查找成功, 否则求下一地址Hi,直至r[Hi] = NULL (查找不成功)
  或r[Hi].key = K (查找成功)为止。
 
//--- 开放定址哈希表的存储结构 ---

int hashsize[] = { 997, ... }; // 哈希表容量递增表,一个合适的素数序列
typedef struct {
ElemType *elem; // 数据元素存储基址, 动态分配数组
int count; // 当前数据元素个数
int sizeindex; // hashsize[sizeindex]为当前容量
} HashTable;
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1 
Status SearchHash (HashTable H, KeyType K, int &p, int &c) {
// 在开放定址哈希表H中查找关键码为K的元素,若查找成功,以p指示待查数据元素在表中位置,并返回SUCCESS;否则,以p指示插入位置,并返回UNSUCCESS, c用以计冲突次数,其初值置零,供建表插入时参考
p = Hash(K); // 求得哈希地址
while ( H.elem[p].key != NULLKEY && !EQ(K, H.elem[p].key))
// 该位置中填有记录并且关键字不相等
collision(p, ++c); // 求得下一探查地址p
if (EQ(K, H.elem[p].key))
return SUCCESS; // 查找成功,p返回待查数据元素位置
else return UNSUCCESS;// 查找不成功,p返回的是插入位置
} // SearchHash

通过调用查找算法实现了开放定址哈希表的插入操作。

Status InsertHash (HashTable &H, Elemtype e) {
// 查找不成功时插入数据元素e到开放定址哈希表H中,并返回OK;若冲突次数过大,则//重建哈希表
c = 0;
if ( HashSearch ( H, e.key, p, c ) == SUCCESS )
return DUPLICATE; // 表中已有与e有相同关键字的元素
else if ( c < hashsize[H.sizeindex]/2 ) { // 冲突次数c未达到上限,(阀值c可调)
H.elem[p] = e; ++H.count; return OK; // 插入e
}
else RecreateHashTable(H); // 重建哈希表
} // InsertHash

可见,无论查找成功与否,ASL均不为零。

决定哈希表查找的ASL的因素:
1. 选用的哈希函数;
2. 选用的处理冲突的方法;
3. 哈希表饱和的程度,装载因子α=n/m 值的大小一般情况下,可以认为选用的哈希函数是“均匀”的,则在讨论ASL时,可以不考虑它的因素。哈希表的ASL是处理冲突方法和装载因子的函数。可以证明查找成功时有下列结果:

 
 
5. 哈希表的删除操作
  从哈希表中删除记录时,要作特殊处理,相应地要修改查找算法对静态查找表,有时也可能找到不发生冲突的哈希函数。 即此时的哈希表的ASL=0, 此类哈希函数为理想(perfect)的哈希函数

哈希表及哈希表查找相关概念(转)相关推荐

  1. PAT甲级1145 Hashing - Average Search Time:[C++题解]哈希表、哈希表开放寻址法、二次探测法、求平均查找次数

    文章目录 题目分析 题目链接 题目分析 来源:acwing 本题的分析见另一道PAT的题目:PAT甲级1078 Hashing:[C++题解]哈希表.哈希表开放寻址法.二次探测法链接的题目就是让建立h ...

  2. ds哈希查找—二次探测再散列_大白话之哈希表和哈希算法

    哈希表概念 哈希表(散列表),是基于关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数(哈希函数 ...

  3. 数据结构-使用哈希存储将数据存入哈希表中,并进行查找

    主函数 #include "./fun.h"int main(int argc, const char *argv[]) {int arr[10] = {25,51,8,22,26 ...

  4. python 哈希表_哈希表哪家强?编程语言找你来帮忙!

    点击关注上方"五分钟学算法", 设为"置顶或星标",第一时间送达干货. 转自编程技术宇宙 哈希表华山论剑 比特宇宙编程语言联合委员会准备举办一次大会,主题为哈希 ...

  5. 【Python算法】哈希存储、哈希表、散列表原理

    哈希表的定义: 哈希存储的基本思想是以关键字Key为自变量,通过一定的函数关系(散列函数或哈希函数),计算出对应的函数值(哈希地址),以这个值作为数据元素的地址,并将数据元素存入到相应地址的存储单元中 ...

  6. 高级数据结构与算法 | 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶

    文章目录 哈希 哈希函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列的解决方法 开散列的解决方法 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) 插入 查找 删除 完整 ...

  7. 哈希表及哈希冲突解决办法

    哈希表及哈希冲突解决办法 目录 什么是哈希表? 哈希表的数据结构 哈希冲突 哈希冲突解决办法 1. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直 ...

  8. 哈希表添加哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构。typedef enum{ HASH_OK, -icoding

    哈希表添加 哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构.也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加 ...

  9. 哈希桶 entry_哈希表代码实现

    哈希表的主要用处:快速的数据存储和查找.例如,在我们日常上网过程中搜索某条信息的时候,信息的存储方式决定了查找该信息的速度,哈希表结合了数组的便捷访问和链表的便捷查找和删除的特点. 实现方式:通过哈希 ...

最新文章

  1. 数据结构与算法:归并排序
  2. 三个字帮大家总结一下刘强东事件
  3. JavaScript数组方法速查手册
  4. origin如何将多个曲线放在一张图_Origin入门教程(十二):误差棒棒棒棒儿
  5. 线性表--数组实现+模板+迭代器
  6. Pytorch state_dict介绍
  7. Ubuntu16.04+ ROS kinetic 使用kinect2 ORK功能包 linemod算法实现可乐罐识别
  8. 最优秀的微信小程序UI组件库
  9. 矩阵转置+矩阵相加(三元组)
  10. 什么是嵌入式服务器?为什么要使用嵌入式服务器? -- java面试
  11. Java显示文件层级目录函数_[转载]文件和目录复制函数
  12. pwm一个时间单位_详解PWM原理、频率与占空比
  13. 一只小蜜蜂 C语言 函数 递归
  14. Android手机平板根目录详解
  15. 不做etl sql 怎么直接取_不管茄子怎么做,直接下锅是大错!多加1步,茄子更入味,不变色...
  16. 3. Base64用途和原理
  17. Python实现文件简单加解密
  18. python配什么数据库_[宜配屋]听图阁
  19. android6支持内存卡,诺基亚6可以插内存卡吗 Nokia 6支持内存卡扩展吗
  20. rstp要点1:端口优先级为什么是16的倍数

热门文章

  1. 百度地图infoWindow圆角处理
  2. JMeter入门(3):录制JMeter脚本
  3. MAC下搭建java的开发环境
  4. 设计模式Adapter模式的五分钟
  5. IT接口——Micro USB带来的市场影响力
  6. .NET正则表达式使用高级技巧之替换类
  7. 增加数组下标_数组以及ArrayList源码解析
  8. stm32串口传输数据第一个数据被吞_STM32串口第一个字节丢失问题的分析过程
  9. kubeadm 部署全过程问题解决记录
  10. CentOS6.2安装redmine2.3