【第21期】观点:人工智能到底用 GPU?还是用 FPGA?

理解Hash表

转载 2016年08月30日 23:11:59

哈希表是种数据结构,它可以提供快速的插入操作和查找操作。第一次接触哈希表时,它的优点多得让人难以置信。不论哈希表中有多少数据,插入和删除(有时包括侧除)只需要接近常量的时间即0(1)的时间级。

实际上,这只需要几条机器指令。
对哈希表的使用者一一人来说,这是一瞬间的事。哈希表运算得非常快,在计算机程序中,如果需要在一秒种内查找上千条记录通常使用哈希表(例如拼写检查器)哈希表的速度明显比树快,树的操作通常需要O(N)的时间级。哈希表不仅速度快,编程实现也相对容易。

哈希表也有一些缺点它是基与数组的,数组创建后难于扩展某些哈希表被基本填满时,性能下降得非常严重,所以程序虽必须要清楚表中将要存储多少数据(或者准备好定期地把数据转移到更大的哈希表中,这是个费时的过程)。而且,也没有一种简便的方法可以以任何一种顺序〔例如从小到大)遍历表中的数据项。如果需要这种能力,就只能选择其他数据结构。然而如果不需要有序遍历数据,井且可以提前预测数据量的大小。那么哈希表在速度和易用性方面是无与伦比的。
散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位:
  1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a•key + b,其中a和b为常数(这种散列函数叫做自身函数)
  2. 数字分析法
  3. 平方取中法
  4. 折叠法
  5. 随机数法
  6. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p, p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。
  
1. 开放寻址法
Hi=(H(key) + di) MOD m, i=1,2,…, k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为增量序列,可有下列三种取法:
  1. di=1,2,3,…, m-1,称线性探测再散列;
  2. di=1^2, (-1)^2, 2^2,(-2)^2, (3)^2, …, ±(k)^2,(k<=m/2)称二次探测再散列;
  3. di=伪随机数序列,称伪随机探测再散列。
  
2. 再散列法
Hi=RHi(key), i=1,2,…,k RHi均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。

3. 链地址法(拉链法)

当存储结构是链表时,多采用拉链法,用拉链法处理冲突的办法是:把具有相同散列地址的关键字(同义词)值放在同一个单链表中,称为同义词链表。有m个散列地址就有m个链表,同时用指针数组T[0..m-1]存放各个链表的头指针,凡是散列地址为i的记录都以结点方式插入到以T[i]为指针的单链表中。T中各分量的初值应为空指针。

例如,用拉链法构造散列表如图所示。

  这里写图片描述
  
  用拉链法处理冲突,虽然比开放定址法多占用一些存储空间用做链接指针,但它可以减少在插入和查找过程中同关键字平均比较次数(平均查找长度),这是因为,在拉链法中待比较的结点都是同义词结点,而在开放定址法中,待比较的结点不仅包含有同义词结点,而且包含有非同义词结点,往往非同义词结点比同义词结点还要多。
  我们知道,对前5个关键字的查找,每一个仅需要比较一次,对关键字49和24的查找,则需要比较2次,对关键字38的查找则需要比较4次,而对43的查找则需要比较3次。因此,对用线性探测法构造的散列表的平均查找长度为:
    ASL=(1×5+2×2+3×1+4×1)/9 ≈1.78
而用拉链法构造的散列表上查找成功的平均查找长度为:
    ASL=(1×5+2×3+3×1)/9≈1.55
显然,开放定址法处理冲突的的平均查找长度要高于拉链法处理冲突的平均查找长度。

举报

相关文章推荐

深入理解Oracle表(5):三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图

Hash Join只能用于相等连接,且只能在CBO优化器模式下。相对于nested loop join,hash join更适合处理大型结果集        Hash Join的执行计划第1个是ha...

深入理解Oracle表(5):三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图

Hash Join只能用于相等连接,且只能在CBO优化器模式下。相对于nested loop join,hash join更适合处理大型结果集 Hash Join的执行计划第1个是hash表(build table),第2个探查表(probe table),一般不叫内外表,nested loop才有内外表 Hash表也就是所谓的内表,探查表所谓的外表 两者的执行计划形如: nested loop outer table --驱动表 in

理解哈希表2(Hash Table)

理解哈希表(Hash Table)用于确定:某个元素是否在已知集合中。本质上和排序+二分法的查找一样,都是把已知集合的本质特征提取出来,就像匹配时,用主分量分析一样。实现起来,把已知集合的数据经过处理...

Hash表的理解以及实现

1. 理解 为每个要被存储的对象给定一个关键字,用一个Hash函数,把这个关键字映射到一个存储单元的地址. 这样, 在查找这个对象的时候, 只需要知道该对象的关键字. 再通过Hash函数, 便可以直接到该地址下的内存单元中去寻找所需要的数据. 但是,这当中又存在一个问题.. 对于每个不同的关键字. 通过Hash函数得到的地址是不是

深入理解HashMap(及hash函数的真正巧妙之处)

深入理解HashMap(及hash函数的真正巧妙之处) 博客分类:  Java 数据结构算法编程  原文地址:http://www.iteye.com/topic/5394...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)