HashTable
是一种非常常见且用途十分广泛的数据结构,使用 HashTable
可以大大的提高数据的检索速度,是一种非常优秀的结构。
1.Hash
算法
散列(哈希)是一种对资料的处理方法,通过某种特定的函数/算法(称为散列函数/算法)将要检索的项与用来检索的索引(称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构(称为散列表)。
一个典型的 Hash
算法是将整数除以一个常量并且取余法,得到的余数就是散列值,本文是用的是这种算法。
2.HashTable
哈希表(散列表)是根据键(Key
)直接访问内存存储位置的数据结构。根据键(Key
)值将数据映射到内存中一个位置的函数称为哈希函数,根据哈希函数建立的记录数据的表称为哈希表。
HashTable
的特点:
-
若关键字为
k
,则其值存放在f(k)
的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f
为散列函数,按这个思想建立的表为散列表。 -
对不同的关键字可能得到同一散列地址,即
k1≠k2
,而f(k1) = f(k2)
,这种现象称为冲突。 -
若对于关键字集合中的任一个关键字,经散列函数映象到地址集合中任何一个地址的概率是相等的,则称此类散列函数为均匀散列函数(
Uniform Hash function
),这就是使关键字经过散列函数得到一个“随机的地址”,从而减少冲突。
3、处理冲突的方法
(1)开放地址法
开放定址法就是产生冲突之后去寻找下一个空闲的空间。函数定义为:
其中,hash(key) 是哈希函数,di 是增量序列,i 为已冲突的次数。
- 线性探测法:di= i ,或者其他线性函数。相当于逐个探测存放地址的表,直到查找到一个空单元,然后放置在该单元。
- 平方探测法:
(2)链表法
这是另外一种类型解决冲突的办法,散列到同一位置的元素,不是继续往下探测,而是在这个位置是一个链表,这些元素则都放到这一个链表上。
(3)再散列法
如果一次不够,就再来一次,直到冲突不再发生。
(4)建立公共溢出区
将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表(注意:在这个方法里面是把元素分开两个表来存储)。
3、HashTable
的 Python
实现
使用开发地址法(线性探测)实现一个简单的 HashTable
。
class Hash:
# 表的长度定位11
def __init__(self):
self.hash_table=[[None,None]for i in range(11)]
# 散列函数
def hash(self,k,i):
h_value=(k+i)%11
if self.hash_table[h_value][0]==k:
return h_value
if self.hash_table[h_value][0]!=None:
i+=1
h_value=self.hash(k,i)
return h_value
def put(self,k,v):
hash_v=self.hash(k,0)
self.hash_table[hash_v][0]=k
self.hash_table[hash_v][1]=v
def get(self