散列表(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. spring-注解配置-junit整合测试-aop

    1 使用注解配置spring 1.1 步骤 导包4+2+spring-aop 1.为主配置文件引入新的命名空间(约束) 2.开启使用注解代理配置文件 3.在类中使用注解完成配置 1.2 将对象注册到容 ...

  2. VS2005连接MySQL C API

    1.在属性添加:附加目录,附加依赖库,附加库目录: 2.在stdafx.h中加入: #include <winsock.h> #include "mysql.h" 3. ...

  3. COOK50小结

    题目链接 很遗憾.看到第五题的通过人数就不敢做了.待日后补上. A题 求最长的连续子序列,使得他们满足gcd为1. 如果有相邻的两个数的gcd为1,那么整个序列的gcd值也就是1, 否则就是该序列不存 ...

  4. jeecms 强大的采集功能优化 转载 https://blog.csdn.net/jeff06143132/article/details/7099003

    ========================================================= 没办法附件上传不了,AcquisitionSvcImpl.java类: //---- ...

  5. 【Django入坑之路】Models操作

    1:字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列,必须填入参数 pr ...

  6. 数据库安全 (ch.4)

    4.2.4 授权与回收 使用 Grant 授予权限 使用Revoke 回收权限 Grant [权限] ON *.. to * [with grant option] with grant option ...

  7. pstree进程管理

    功能:pstree命令列出当前的进程,以及它们的树状结构. 格式:pstree [选项] [pid|user] 主要选项如下: -a:显示执行程序的命令与完整参数. -c:取消同名程序,合并显示. - ...

  8. Struts_客户列表练习

    1.导包 2.配置文件struts.xml 3.创建CustomerAction 4.修改menu.jsp和List.jsp 5.配置web.xml

  9. javascript最大公约数与最小公倍数

    var a = 5 ; var b = 15 ; var min = Math.min(a,b); var max = Math.max(a,b); // for循环求最大公约数 for(var i ...

  10. linux交换两个文件的文件名