哈希表(HashTable)笔记

深入底层学习php,肯定少不了hash表的学些,于是参考维基百科,做了以下笔记,并且实践上用c语言实现了其中一种hash表;


一. HashTable在PHP中的地位

首先要知道,php中的变量存储是通过zval这个结构体来实现的,而zval的查找寻址是通过php启动内核里面的HashTable来实现的。
除此之外,一个HashTable有很多元素,在php内核里叫做bucket。然而每个bucket的大小是固定的, 所以如果我们想在bucket里存储任意数据时,最好的办法便是申请一块内存保存数据, 然后在bucket里保存它的指针。

由此可见,hashtable可以说在php中的地位很关键。


二. Hashtable的概念

hashtable中文名是哈希表,是根据键(Key)而直接访问在内存存储位置的数据结构。

从定义上可以看出关键点有两个:
(1)需要有key和存储位置的映射关系,称作散列函数*hash(key)【若均匀分布,则称为均匀散列函数*】,计算值称为散列地址;
(2)需要处理不同key产出相同hash(key)的case,称为处理冲突


三. 常见构造散列函数的方法

(1)直接地址法:hash(k)=k或 hash(k)=a k+b 其中a,b为常数(这种散列函数叫做自身函数);
(2)数字分析法
(3)平方取中法:取关键字平方后的中间几位为哈希地址【因为平方后中间几位和关键字的大部分位都有关系】。
(4)折叠法: 讲关键字按指定位数折叠,然后舍去相对于最大地址的高位(哈希表的地址最大值取余数),再得出地址;
(5)随机数法
(6)除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。


四. 常见的处理冲突的方法

(1)开放定址法
散列函数: hash(k) = (hash0(k) + d) mod m
当不同的k冲突时,就通过以下方式改变d来寻找新的可用的地址,
A. 线性探测:d = 1,2 , 3….. m
B. 平方探测:d = 1^2, 2^2 …k^2 (k<=m/2)
C. 伪随随机探测:d=预先设定的伪随机数

(2)单独链表法: 就是当不同key得出相同hash(k)时,就在当前hash(k)下建立链表存储键值;
(3)双散列法:相对于开放地址法,就是在插入键值和查询键值时使用两套散列函数;
(4)再散列法:hash(k)=hash(hash(k));


五. 实践时使用的hashtable-c语言版例子

(1)使用“折叠法”构造散列函数
(2)使用“单独链表法”处理冲突
例程见如下资源:

http://download.csdn.net/detail/gavin_new/9755014

使用:
linux环境下,解压后,敲入命令:
(1)make clean && make
(3)./target

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章