散列表(hash table): 也称为哈希表. 根据wikipedia的定义:是根据关键字(Key value)而直接访问在内存存储位置的数据结构。也就是说,它通过把键值通过一个函数的计算,映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数(hash function),存放记录的数组称做散列表(hash table)

为了方便理解概念.举个与散列表原理相似的实际生活中应用例子--电话簿.一般的电话簿是按照电话用户的姓的首字母a-z顺序进行排列的,首字母相同的按照姓的第二个字母进行排列,以此类推(可能还有其他的规则,比如地点,时间,或者几种规则的混合).当我们要查找某人的电话号码时,我们会根据用户的姓推导出对应的首字母,然后再按照首字母去对应的子目录下查找和该用户姓名对应的电话号码.在这个过程中,"用户的姓名"对应于散列表中的关键字(key),"推导的规则"好比散列表中的哈希函数(hash function).号码簿即散列表. 散列表是根据将关键字代入哈希函数中求得的值进行存储,而非根据关键字. 那就有会存在这样的一种情况,如果将不同的关键字代入哈希函数求得的值相同,那散列表如何处理呢? 这种不同关键字而哈希函数值相同的情况称作碰撞(collision).

对于散列表的设计,建立以及建立后数据的查找,插入和删除等操作的性能,问题的重心主要在两个方面:哈希函数和碰撞。

哈希函数:

对于一个好的哈希函数来讲,每个关键字都等可能地分配到m(假设散列表提供了m个槽位(slot))的槽位中,并且与其他关键字已经分配到哪个槽位无关。确切来讲要求该函数是符合独立同分布的特点。但是在实际中,我们很难找出关键字的分布规律. 一种好的方法是以独立于数据中可能存在的任何模式的方法导出散列值(算法导论 第二版). 对于这句话我的理解是: 在实际产生的数据中,数据的内容,格式等很大程度上可能存在着联系和聚集的情况, 即分布不均匀, 而散列表顾名思义,需要"散列",如果采用数据原有的模式如内容,格式等与"散列"的精神冲突的可能性很大.

下面介绍几种哈希函数的设计方案:

将关键字解释为自然数: 我们都知道计算机的灵魂只有"0"和"1", 与它们比较接近的是数字,或者更小范围的整数,自然数. 如果能够将信息或数据转化为自然数,计算机处理数字要方便的多. 同时对于哈希函数来讲,处理数字更便利.基于这两点,散列表要求的关键字,我们可以将原始关键字进行转化自然数形式.

1.除法散列法

散列函数: h(k)= k mod m

m: 散列表槽数  k:关键字   h(k): 数组地址索引

函数关键: m 的选择,一般选择与2的整数次幂不太接近的质数

2. 乘法散列表

散列函数: 

两个步骤:

1. 用关键字k乘上常数A(0<k<1), 取出kA的小数部分。

2. 用m乘以这个小数部分,再对乘积的结果取底。

优点: 对于m的取值没有太多的要求,一般选择以2为底的某个次幂。 A的取值为0.618 033 比较理想。

无论怎么设计哈希函数,对于"碰撞"情况的发生都是不能绝对避免的,所以接下来的问题是怎么解决"碰撞"的情况. 现在普遍的方法有链接法,和开放寻址法.下面阐述的炒作都忽略卫星数据,只考虑关键字。

链接法:

顾名思义,是通过链表将碰撞的数据进行相互链接到同一槽上. 对于插入,删除,查找操作,在完成查找对应槽的操作后(O(1)),接下来的既是对链表进行操作。假设有n个关键字,m 条槽

成功查找:O(1+n/m), 失败查找:O(1+n/m)

插入有不同的规则, 一般是插入到链表头部(即与槽相连接部分).

开放寻址法:

将所有的元素都存入到散列表中,不通过链表来解决碰撞问题,如果产生碰撞,通过改变参数来使用哈希函数中重新寻找空槽. 由于要求所有元素都存入散列表中,这就需要n<=m,及关键字总数小于槽数。

优点: 不需要使用指针,节省了空间,潜在的效果是减少碰撞,提高了查找速度。

插入: 对于每一个关键字k, 都可以按照如下的序列<h(k,0),h(k,1)...h(k,n-1)>,依次进行,直到查找到空槽插入关键字为止.

查找: 和插入算法是一样的,只是查找过程中如果碰到一个空槽就停止,返回信息

删除: 由于查找的规则,所以删除一项时,应该将该空槽进行标记,如Deleted

散列表(Hash Table)的更多相关文章

  1. [转载] 散列表(Hash Table)从理论到实用(上)

    转载自:白话算法(6) 散列表(Hash Table)从理论到实用(上) 处理实际问题的一般数学方法是,首先提炼出问题的本质元素,然后把它看作一个比现实无限宽广的可能性系统,这个系统中的实质关系可以通 ...

  2. [转载] 散列表(Hash Table)从理论到实用(中)

    转载自:白话算法(6) 散列表(Hash Table)从理论到实用(中) 不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好 ...

  3. [转载] 散列表(Hash Table) 从理论到实用(下)

    转载自: 白话算法(6) 散列表(Hash Table) 从理论到实用(下) [澈丹,我想要个钻戒.][小北,等等吧,等我再修行两年,你把我烧了,舍利子比钻戒值钱.] ——自扯自蛋 无论开发一个程序还 ...

  4. Java 集合 散列表hash table

    Java 集合 散列表hash table @author ixenos 摘要:hash table用链表数组实现.解决散列表的冲突:开放地址法 和 链地址法(冲突链表方式) hash table 是 ...

  5. 散列表(Hash table)及其构造

    散列表(Hash table) 散列表,是根据关键码值(Key value)而直接进行访问的数据结构.它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录 ...

  6. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

  7. 算法导论-散列表(Hash Table)-大量数据快速查找算法

    目录 引言 直接寻址 散列寻址 散列函数 除法散列 乘法散列 全域散列 完全散列 碰撞处理方法 链表法 开放寻址法 线性探查 二次探查 双重散列 随机散列 再散列问题 完整源码(C++) 参考资料 内 ...

  8. 白话算法(6) 散列表(Hash Table)从理论到实用(中)

    不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好的)方法.推动科技进步的人,永远是那些敢于问出比外行更天真.更外行的问题, ...

  9. 白话算法(6) 散列表(Hash Table)从理论到实用(上)

    处理实际问题的一般数学方法是,首先提炼出问题的本质元素,然后把它看作一个比现实无限宽广的可能性系统,这个系统中的实质关系可以通过一般化的推理来论证理解,并可归纳成一般公式,而这个一般公式适用于任何特殊 ...

随机推荐

  1. 移动相关的css

    1.首先认识第一个apple-mobile-web-app-capable 删除默认的苹果工具栏和菜单栏. <meta name="apple-mobile-web-app-capab ...

  2. Hdfs的列存储和行存储

    列可以分开存储,对于重复性高的数据压缩比会高,但是在元组(行shi)恢复会比较消耗性能 于传统列存储不同 是行组会存储于同一节点中,列扫描会比较快(因为只需扫描一个行组)

  3. [Array]189. Rotate Array

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array  ...

  4. LUOGU P1978 集合

    题目描述 集合是数学中的一个概念,用通俗的话来讲就是:一大堆数在一起就构成了集合.集合有如 下的特性: •无序性:任一个集合中,每个元素的地位都是相同的,元素之间是无序的. •互异性:一个集合中,任何 ...

  5. Lvs 环境搭建 vbox搭建centos6.9 vbox设置 centos上安装nginx

    1.现在vbox上虚拟出3个虚拟机,分别为负载均衡器(Load Balance).实际服务器1(Real server1).实际服务器2(Real Server2) 要点: :vbox系统网络连接方式 ...

  6. call(this)自记

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. poj 1679 The Unique MST 判断最小生成树是否唯一(图论)

    借用的是Kruskal的并查集,算法中的一点添加和改动. 通过判定其中有多少条可选的边,然后跟最小生成树所需边做比较,可选的边多于所选边,那么肯定方案不唯一. 如果不知道这个最小生成树的算法,还是先去 ...

  8. JS---案例:滚动条

    案例:滚动条 html框架分为4部分,最外面的div, 放文字的div, 装滚动条的div层,以及滚动条本身放在一个div里面 <!DOCTYPE html> <html> & ...

  9. 2019.8.14 NOIP模拟测试21 反思总结

    模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...

  10. redis书籍

    redis中文官网命令网址:http://doc.redisfans.com/ redis英文官网命令网址:https://redis.io/commands redis书籍 由 Karl Segui ...