【数据结构和算法】Hash Table

待续

Hash Table:


1. 什么是?

2. 什么问题用?

3. 怎么用?

4. 实际应用? 

5. 实际代码? 

6. 思考问题?



1. 什么是?


参考:

http://www.cnblogs.com/vamei/archive/2013/03/24/2970339.html


哈希表(hash table)是从一个集合A到另一个集合B的映射(mapping)

上述对应过程称为hashing。A中元素a对应B中元素b,a被称为键值(key),b被称为a的hash值(hash value)

哈希表的核心是一个哈希函数(hash function),这个函数规定了集合A中的元素如何对应到集合B中的元素。




4. 实际应用?


参考:

http://www.cnblogs.com/vamei/archive/2013/03/24/2970339.html


Ethernet中的FCS:参看小喇叭开始广播 (以太网与WiFi协议)

IP协议中的checksum:参看我尽力 (IP协议详解)

git中的hash值:参看版本管理三国志


登陆密码:

使用MD5、SHA或者其他算法作为hash函数:密码字符串---》hash值

效果:所使用的hash函数有很好的单向性:很难从hash值去推测键值


HASH与搜索:

hash函数:搜索对象---》存储位置

效果:一次hash,将对象所在位置找到

过程:

以人名(字符串)为键值,以数组下标为hash值。每个数组元素中存储有一个指针,指向记录 (有人名和电话号码)。

在搜索"Vamei"的记录时,可以经过hash,得到hash值498,再直接读取records[498],就可以读取记录了。

数组records的大小为HASHSIZE,HASHSIZE被选择为质数,以便hash值能更加均匀的分布。

Python: Hashing

a = 'Obama'
value = 0

for i in a:
	value+=ord(i)
	
print ('Hash value of %r is %r') %(a,value)
<p class="p1"><span class="s1">Hash value of 'Obama' is 480</span></p>

比较:


如果不采用hash,而只是在一个数组中搜索的话,我们需要依次访问每个记录,直到找到目标记录,算法复杂度为n。

利用键值和hash函数,来选择适当的下标进行搜索。在没有hash碰撞的前提下,我们只需要选择一次,就可以保证该下标指向的元素是我们想要的元素。

由于数组可以根据数组下标进行随机存取(random access,算法复杂度为1),所以搜索操作将取决于hash函数的复杂程度。



6. 思考问题?

hash冲突:上面的hash函数中,"Obama"和"Oaamb"有相同的hash值


一个方案是将发生冲突的记录用链表储存起来,让hash值指向该链表,这叫做open hashing:

先根据hash值找到链表,再根据key值遍历搜索链表,直到找到记录。


open hashing需要使用指针。我们有时候想要避免使用指针,以保持随机存储的优势,所以采用closed hashing的方式来解决冲突。


将冲突记录放在数组中依然闲置的位置,

比如图中Obama被插入后,随后的Oaamb也被hash到480位置。但由于480被占据,Oaamb探测到下一个闲置位置(通过将hash值加1),并记录。


closed hashing的关键在如何探测下一个位置。

在第i次的时候,我们应该探测POSITION(i)=(h(x) + f(i)) % HASHSIZE的位置。

上面将hash值加1的方式,就相当于设定f(i) = 1。当我们在搜索的时候,就可以利用POSITION(i),依次探测记录可能出现的位置,直到找到记录。

f(i)的选择会带来不同的结果

如果数组比较满,那么closed hashing需要进行许多次探测才能找到空位。这样将大大减小插入和搜索的效率。

这种情况下,需要增大HASHSIZE,并将原来的记录放入到新的比较大的数组中。这样的操作称为rehashing









其他参考:

http://blog.csdn.net/liufei_learning/article/details/19220391

kernel 中的hash table的实现 http://blog.csdn.net/zdl1016/article/details/8882083

http://www.importnew.com/16138.html

从头到尾彻底解析Hash表算法 http://kb.cnblogs.com/page/189480/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值