散列表(哈希表)

序言:

如果将一系列的记录按照关键字的某种函数存储,那么在查找某个数据的时候就可以直接通过关键字计算出来了,而不在需要“比较”,这样会非常高效,这就是散列技术。

所以散列技术就是:     存储位置=f(关键字)        不管是记录的存储还是查找,都用这种方法

散列技术具有很高的效率,但是使用起来有一些限制。如1个关键字对应多个记录的情况(比如在一个学校的学生中按性别查找,则对应太多的记录),此外散列技术同样不适合于范围查找和排序等操作。

一、散列函数的构造

在设计散了函数的时候主要考虑两个原则:

(1)计算效率高:散列的优点就是高效,如果通过关键字计算地址的时间比其他查找方法比较用的时间还长,那么要它还有何用呢?

(2)散列地址分布均匀:这样才能保证存储空间的有效利用,也可以减少处理冲突而耗费的时间。

常用散列函数的构造方法:

(1)直接定址法:
取某个关键字的线性函数作为散列地址:f(key)=a*key+b      (a,b取常数)
此法需要事先知道关键字的分布情况,适合查找数据较少且连续的记录。
(2) 数字分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
此法适合关键字位数比较大的情况。
(3)平方取中法取关键字平方后的中间几位作为散列地址。
此法比较适合不知道关键字分布,而位数又不是很大的情况。 
(4)折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。数位叠加可以有移位叠加和间界叠加两种方法。移位叠加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加。
此法适合事先不知道关键字分布且位数较多的情况。
(5)除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。
(6) 随机数法:选择一随机数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。

二、处理冲突的方法

(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) 链地址法(拉链法):将所有同义词记录在一个链表中,每次产生冲突,就直接在链表后增加一个结点而已。

(4) 建立一个公共溢出区:一旦发生冲突就把数据放在放在里面。

时间: 2024-08-02 12:25:48

散列表(哈希表)的相关文章

[BS]散列表 哈希表 Hash table

<第五章> 散 列 散列表的实现常常叫做散列(hashing).散列是一种用于以常数平均时间执行插入.删除和查找的技术. 关于散列有一个很重要的概念:散列函数.散列函数是散列的关键处之一,散列函数又是基于映射机制的一种对应关系(一般是多对一的关系). 这章可以分为5个部分:一般想法,散列函数,分离链接法,开放定址法(可分为线性探测.平方探测.双散列).再散列.可扩散列. 本文只写到前四节.即:一般想法,散列函数,分离链接法,开放定址法(可分为线性探测.平方探测.双散列)() 第五章第一节:一般

散列表之直接寻址表

散列表之直接寻址表 直接寻址表的定义 直接寻址表的操作 直接寻址表的代码实现 dataNode的定义 直接寻址表的定义 测试文件 编译运行 总结 注意: 本文中的所有代码你可以在这里: https://github.com/qeesung/algorithm/tree/master/chapter11/11-1/directAddr(这里的会及时更新) 或者这里: http://download.csdn.net/detail/ii1245712564/8793509 找到 散列表之直接寻址表

[数据结构] 散列表(哈希表)

散列表(哈希表) 比较难理解的官方定义:散列表/哈希表(Hash table),是根据关键码值(Key value)而直接进行访问的数据结构.它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. 举个例子,我们在查找中文字典时.假设我们要查找"翁weng",我们根据weng找到了对应的页码233,这个过程就是根据关键码值映射得到了表中的位置.然后我们在字典这个散列表中,根据我们刚才得到的位置 233页,直接访问了"

数据结构与算法----散列/哈希

1. 简介 散列表的实现叫散列hashing,散列用于以常数平均时间执行 插入.删除.查找,不支持排序.findMin.findMax. 查找关键字不需要 比较 在一个记录的存储位置和它的关键字之间建立映射关系:key--f(key)   这个关系就是散列函数/哈希函数.将一些记录存储在一块 连续 的存储空间,这块空间就是散列表/哈希表. 与线性表.树.图比较: 数据元素之间没有什么逻辑关系,也不能用连线图表示出来. 问题: 关键字不同,但通过散列函数计算的结果相同,即出现了冲突 collisi

HashTable-哈希表/散列表

HashTable-散列表/哈希表,是根据关键字(key)而直接访问在内存存储位置的数据结构.它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表. 构造哈希表的几种方法 直接定址法--取关键字的某个线性函数为散列地址,Hash(Key)= Key 或 Hash(Key)= A*Key + B,A.B为常数. 除留余数法--取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址.Hash(Key)= Key % P. 平方取中法

哈希表线性探测

HashTable-散列表/哈希表,是根据关键字(key)而直接访问在内存存储位置的数据结构. 它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表. 哈希冲突/哈希碰撞 不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的值哈希地址,我们称这种情况为哈希冲突.任意的散列函数都不能避免产生冲突. 我给大家介绍的是哈希表的线性探测,线性探测的基本思路: 1.用一个数据除以散列表的长度,余数是多少,就把这个数放在散列表下标相同

MySQL中哈希表

也称为散列表 由直接寻址表改进而来.先看直接寻址表 当关键字的全域U比较小时,直接寻址是一种简单而有效的技术.加入某应用要用到一个动态集合,其中每个元素都有一个取自全域U={0,1,...,m-1}的关键字.同时假设没有两个元素具有相同的关键字 用一个数组(即直接寻址表)T[0...m-1]表示动态集合,其中每个位置(或称槽或桶)对应全域U中的一个关键字.图5-38说明了这个问题.槽K指向集合的一个关键字为k的元素.如果该集合没有关键字k的元素,则T[k]=NULL 直接寻址存在一个很明显的问题

算法导论-散列表(Hash Table)

目录 引言 直接寻址 散列寻址 散列函数 除法散列 乘法散列 全域散列 完全散列 碰撞处理方法 链表法 开放寻址法 线性探查 二次探查 双重散列 随机散列 再散列问题 完整源码(C++) 参考资料 内容 1.引言 如果想在一个n个元素的列表中,查询元素x是否存在于列表中,首先想到的就是从头到尾遍历一遍列表,逐个进行比较,这种方法效率是Θ(n):当然,如果列表是已经排好序的话,可以采用二分查找算法进行查找,这时效率提升到Θ(logn);  本文中,我们介绍散列表(HashTable),能使查找效率

哈希表 hash table

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. 给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数. 首先问题规模确定,例如5台服务器怎么把数据散落在5台上面呢,就用到了hash算法