【经典数据结构】哈希表

哈希表的基本概念html

  哈希表,也叫散列表,它是基于快速存取的角度设计的,是一种典型的“空间换时间”的作法。哈希表是普通数组的一种推广,由于数组能够直接寻址,故可在O(1)时间内访问数组的任意元素,其中它的插入和删除的时间复杂度也是O(1)。c++

  哈希表是根据关键字(Key Value)而直接进行访问的数据结构。也就是说,它将关键字经过某种规则映射到数组中的某个位置,以加快查找的速度。这个映射规则称为哈希函数(散列函数),存放记录的数组称为哈希表。哈希表创建了关键字和存储地址之间的一种直接映射关系。算法

  若多个不一样的关键字经过哈希函数计算获得相同的数组下标,称其发生了冲突,这些发生冲突的不一样关键字称为同义词。一方面,设计好的HASH函数应尽可能减小这这样的冲突;另外一方面,因为这样的冲突老是不可避免的,因此还要设计好处理冲突的方法。数组

 

哈希函数安全

  全部散列都有以下一个基本特性:若是两个散列值是不相同的(根据同一函数),那么这两个散列值的原始输入也是不相同的(根据同一函数)。那么这两个散列值的原始输入也是不相同的。这个特性使散列函数具备肯定性的结果,具备这种性质的散列函数称为单向散列函数。数据结构

  典型的散列函数都有无限定义域,好比任意长度的字节字符串,和有限的值域,好比固定的比特串。函数

   

经常使用哈希函数学习

  咱们在数据结构这门课程,曾经学习这几种简单经常使用的散列函数,如直接定址法、乘法散列法、除法散列法、除留余数法,折叠法等。加密

  如下咱们介绍工业界比较著名的哈希函数(哈希算法),这些算法一般应用于信息安全领域)。设计

  典型的哈希算法包括MD4,MD5和SHA-1,MD5和SHA-1(安全哈希算法)能够说是目前应用最为普遍的Hash算法,而它们都是以MD4为基础设计的。

 

处理冲突的方法

  任何哈希函数都不可能绝对地避免冲突,为此必须考虑冲突发生时应如何进行处理,即为产生冲突的关键字寻找下一个“空”的Hash地址,因而提出了处理冲突的各类方法。

  1) 链地址法

    链地址法是指把散列在同一槽的全部元素(同义词)都存储在一个线性链表中,这个链表由其散列地址惟一标识。

    给定一个能存放n个元素的、具备m个槽位的散列表T,定义T的装载因子(load factor)α为n/m,即一个链的平均存储元素数。α能够小于、等于或者大于1

  2)开放定址法

    开放定址法是指可存放新表项的空闲地址。既向它的同义词表项开放,又向它的非同义词表项开放。其数学递推公式为(Hi表示冲突发生后第i次探测的散列地址):

          Hi=(H(key)+di)%m

式中,i=1,2,...,k(k<=m-1),m为散列表表长,di为增量序列,di一般有如下几种取法:

  当di=1,2,..,m-1时称为线性探测法。其特色是,冲突发生时顺序查看表中下一个单元,直到找出一个空单元或查遍全表。

  当di=12,-12,22,-22,...,k2,-k2时,其中k<=m/2,又为二次探测法。

  当di是伪随机序列时,称为伪随机探测法。

  3)再散列法

  当冲突发生时,利用另外一个哈希函数再次计算一个地址,直到冲突再也不发生,这种方法称为再哈希法。

  4)创建一个公共溢出区

  一旦由哈希函数获得的地址冲突,就都填入溢出表。

  有如下两点须要说明: 

  1)在开放定址的情形下,不能随便删除表中已有的元素,由于若删除元素将会截断其余具备相同散列地址的元素的查找地址。因此若想删除一个元素时,给它作一个删除标记,进行逻辑删除。但这样作的反作用是,在执行屡次删除后,表面上看起来散列表很满,实际上有许多位置没有利用,所以须要按期维护散列表,要把作删除标记的元素物理删除。

  2)计算查找的平均查找长度ASL时,平均的概念是对表终当前非空元素而言的,并不是是整个表长。计算查找失败的平均查找长度ASL时,平均的概念是针对表长。

 

链地址方法和开放定址法的区别

  1. 链地址法的节点是动态申请的,因此适用于没法肯定建表前没法肯定表长的状况;链地址法的指针须要空间,故当结点规模较小时,开放定址法较为节省空间

  2. 拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,所以平均查找长度较短

  3. 开放定址法为减小冲突,要求装填因子α较小,故当结点规模较大时会浪费不少空间。而拉链法中可取α≥1,且结点较大时,拉链法中增长的指针域可忽略不计,所以节省空间;

 

哈希算法是否能够用来加密?

解答:哈希(hash)就是把任意长度的输入经过哈希算法,变换成固定长度的输出,该输出就是哈希值(散列值)。这种转换是一种压缩映射,使得散列值的空间一般远小于输入的空间,不一样的输入可能会散列成相同的输出,而不可能从散列值来惟一肯定输入值。哈希算法是一种消息摘要uanfa,虽然哈希算法不是一种加密算法,但因为其单向运算,具备必定的不可逆性使其成为加密算法中的一个重要构成部分。

 

一致性哈希:http://blog.codinglabs.org/articles/consistent-hashing.html

 

参考资料:

  1. 《数据结构与算法分析c++描述》 第三版  人民邮电出版社

相关文章
相关标签/搜索