Hash散列及冲突解决

先看看英文的维基百科上的解释:

 

A hash function is any algorithm or subroutine that maps large data sets of variable length, called keys, to smaller data sets of a fixed length. For example, a person's name, having a variable length, could be hashed to a single integer. The values returned by a hash function are called hash values, hash codes, hash sums, checksums or simply hashes.

 

意思是说:hash散列是任何可以把大数据集映射到定长数据集的算法或子程序。

用数学公式解释:假设F是一个包含n个记录的文件空间,Ri为文件中的某个记录(1≤i≤n),keyi是其关键字值,若存在关键字值keyi与记录Ri的地址之间建立某种函数关系,则便可以通过这个函数把关键字值转换成相应记录在文件中的地址。即有:addr(Ri)=H(keyi),其中addr(Ri)为Ri的地址,H(keyi)称为哈希函数。

 

hash散列的应用:

 

1.hashtable:用来快速定位一条记录是否出现在给定集合中。

2.加密:hash算法一般是不可逆的。

3.Bloom filters:构造很大的bit数组,利用多个hash算法,判断一条记录是否已存在。用于邮件的黑名单过滤等。

4.校验:如循环冗余校验等。

5.语言识别和文件比较。

 

常用的著名hash算法:

算法名称 输出大小 (bits) 内部大小 区块大小 长度大小 字符尺寸 碰撞情形
HAVAL 256/224/192/160/128 256 1024 64 32
MD2 128 384 128 No 8 大多数
MD4 128 128 512 64 32
MD5 128 128 512 64 32
PANAMA 256 8736 256 32
RadioGatún Arbitrarily long 58 words 3 words 1-64
RIPEMD 128 128 512 64 32
RIPEMD-128/256 128/256 128/256 512 64 32
RIPEMD-160/320 160/320 160/320 512 64 32
SHA-0 160 160 512 64 32
SHA-1 160 160 512 64 32 有缺陷
SHA-256/224 256/224 256 512 64 32
SHA-512/384 512/384 512 1024 128 64
Tiger(2)-192/160/128 192/160/128 192 512 64 64
WHIRLPOOL 512 512 512 256 8

自己如何实现hash算法?

 

1.直接地址法:取关键字或关键字的某个线性函数值为哈希地址。即:H(key)=key或H(key)=a·key+b

2.数字分析法:假设关键字是以R为基的数(如2,8,10等),并且哈希表中可能出现的关键字都是事先知道的,则可以取关键字的若干数位来组成哈希地址。

3.平方取中法:有时一组关键字在每一位上某些数字的重复出现频率很高,例如:(0100,1100,1200,1160,2060,2163,2261,2262),这时无法是用数字分析法得到较均匀的哈希函数,平方取中法是首先求关键字的平方值,通过平方来扩大差别,然后再选其中的几位或其组合作为哈希地址。该方法适用于关键字位数少而相同的位数多的关键字。

4.折叠法(边界法)与转移法:有时关键字含位数较多,这时可将关键字值从某些地方断开,分成几段,其中一段的长度等于地址的位数,把其余折叠加到它的上面,若产生进位则舍去。

5.除留余数法:取关键字被某个不大于哈希表表长m的数p除后所得的余数作为哈希地址。即:H(key)=key MOD p  (p≤m 一般取p为不大于m的最大素数。)

 

 

如何解决hash冲突?

因为是将无限大量的数据集映射到固定长度的数据集上,难免不同的key映射到同一个位置。

 

1.开放定址法

   Hi=(H(key)+di) mod  m  i=1,2,……,k(k≤m-1)

   其中:H(key)为哈希函数;m为哈希表表长;di为增量序列,有三种取法。

①di=1,2,……,m-1;称为线性探测再散列或线性探查法。

②di=12,-12,22,-22,32,……,±k2,(k≤m/2);称为二次探测再散列。

③di=伪随机数序列,称为伪随机探测再散列

 

2.再哈希法

    Hi=RHi(key)     i=1,2,……,k

    RHi均是不同的哈希函数,即在同义词产生地址冲突时计算另一个哈希函数地址,直到冲突不再发生。这种方法不易产生聚集,但增加了计算的时间。

 

3.链地址法(结合的同义词子表)

    把具有相同散列地址的关键字存放在同一个链表中,称为同义词表。同时用数组T存放各个链表的头指针。凡是散列地址为i的记录都以结点方式插入到以T[i]为头指针的单链表中。

 

4.建立一个公共的溢出区(分离的同义词子表)

    假设哈希函数的值域为[0、、m-1],则设向量HashTable[0、、m-1]为基本表,每个分量存放一个记录,另设立向量OverTable[0、、v]为溢出表。所有关键字和基本表中关键字为同义词的记录,不管它们由哈希函数得到的哈希地址是什么,一旦发生冲突,都填入溢出表。


参考:

http://en.wikipedia.org/wiki/Hash_function

http://blog.sina.com.cn/s/blog_4acd74e80100063n.html

你可能感兴趣的:(hash,冲突,conflict)