码迷,mamicode.com
首页 > 其他好文 > 详细

【经典数据结构】哈希表

时间:2015-08-20 09:06:52      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

哈希表的基本概念

  哈希表,也叫散列表,它是基于快速存取的角度设计的,是一种典型的“空间换时间”的做法。哈希表是普通数组的一种推广,因为数组可以直接寻址,故可在O(1)时间内访问数组的任意元素。

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

  若多个不同的关键字通过哈希函数计算得到相同的数组下标,称其发生了冲突,这些发生冲突的不同关键字称为同义词。一方面,设计好的HASH函数应尽量减少这这样的冲突;另一方面,由于这样的冲突总是不可避免的,所以还要设计好处理冲突的方法。

 

哈希函数

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

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

常用哈希函数

  我们在数据结构这门课程,曾经学习这几种简单常用的散列函数,如直接定址法、数字分析法、平方取中法、除留余数法,折叠法等。

  以下我们介绍工业界比较著名的哈希函数(哈希算法),这些算法通常应用于信息安全领域)。

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

 

处理冲突的方法

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

  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时,平均的概念是针对表长。

【经典数据结构】哈希表

标签:

原文地址:http://www.cnblogs.com/vincently/p/4743891.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!