散列表(Hash Table)
散列表(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)的更多相关文章
- [转载] 散列表(Hash Table)从理论到实用(上)
转载自:白话算法(6) 散列表(Hash Table)从理论到实用(上) 处理实际问题的一般数学方法是,首先提炼出问题的本质元素,然后把它看作一个比现实无限宽广的可能性系统,这个系统中的实质关系可以通 ...
- [转载] 散列表(Hash Table)从理论到实用(中)
转载自:白话算法(6) 散列表(Hash Table)从理论到实用(中) 不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好 ...
- [转载] 散列表(Hash Table) 从理论到实用(下)
转载自: 白话算法(6) 散列表(Hash Table) 从理论到实用(下) [澈丹,我想要个钻戒.][小北,等等吧,等我再修行两年,你把我烧了,舍利子比钻戒值钱.] ——自扯自蛋 无论开发一个程序还 ...
- Java 集合 散列表hash table
Java 集合 散列表hash table @author ixenos 摘要:hash table用链表数组实现.解决散列表的冲突:开放地址法 和 链地址法(冲突链表方式) hash table 是 ...
- 散列表(Hash table)及其构造
散列表(Hash table) 散列表,是根据关键码值(Key value)而直接进行访问的数据结构.它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录 ...
- 散列表(hash table)——算法导论(13)
1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...
- 算法导论-散列表(Hash Table)-大量数据快速查找算法
目录 引言 直接寻址 散列寻址 散列函数 除法散列 乘法散列 全域散列 完全散列 碰撞处理方法 链表法 开放寻址法 线性探查 二次探查 双重散列 随机散列 再散列问题 完整源码(C++) 参考资料 内 ...
- 白话算法(6) 散列表(Hash Table)从理论到实用(中)
不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好的)方法.推动科技进步的人,永远是那些敢于问出比外行更天真.更外行的问题, ...
- 白话算法(6) 散列表(Hash Table)从理论到实用(上)
处理实际问题的一般数学方法是,首先提炼出问题的本质元素,然后把它看作一个比现实无限宽广的可能性系统,这个系统中的实质关系可以通过一般化的推理来论证理解,并可归纳成一般公式,而这个一般公式适用于任何特殊 ...
随机推荐
- KOA 学习(二)
app.listen(...) Koa 应用并非是一个 1-to-1 表征关系的 HTTP 服务器. 一个或多个Koa应用可以被挂载到一起组成一个包含单一 HTTP 服务器的大型应用群. var ko ...
- java 实现文件内容的加密和解密
package com.umapp.test; import java.io.FileInputStream; import java.io.FileOutputStream; import java ...
- HDFS的Web界面
- mybatis学习:mybatis的注解开发CRUD操作
Dao层: public interface IUserDao { /** * 查询所有结果 * @return */ @Select("select * from user") ...
- jmeter断言步骤
在POST /wordpress/wp-login.php请求,也就是名称为submit login form user的请求上点右键, 选择添加 -> 后置处理器 -> CSS/JQue ...
- Leetcode150. Evaluate Reverse Polish Notation逆波兰表达式求值
根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说 ...
- nginx的四个基本功能
Nginx能做什么 1.反向代理2.负载均衡3.HTTP服务器(包含动静分离)4.正向代理 以上就是做网站小编了解到的Nginx在不依赖第三方模块能处理的事情,下面详细说明每种功能怎么做 1.反向代理 ...
- mit课程ocw-mathematics
https://ocw.mit.edu/courses/find-by-topic/#cat=mathematics Course # Course Title Level 1.010 Uncerta ...
- 基础篇-1.5Java的数组
1 引言 每一种编程语言都有其自身的数组概念,大同小异,都是为了存储一堆数据,而Java的数组是用来存储相同类型的数据,如声明一个arr[10]数组,可以用来代替声明10个变量. 2 声明和创建数组 ...
- Zookeeper安装过程
zookeeper的安装我反反复复安装了三次,前两次在root用户下安装都失败了,都启动不起来,第三次我改成普通用户安装,没想到成功了,很不可思议,步骤完全一样,接下来介绍一下具体的安装步骤: 1. ...