📅  最后修改于: 2023-12-03 15:22:23.081000             🧑  作者: Mango
哈希(Hash)是一种将任意大小的数据映射到固定大小的数据的方法。哈希表就是使用哈希技术实现的一种数据结构,它允许快速的插入、删除、查找数据。
使用哈希表实现电话目录,需要以下几个步骤:
定义一个桶数组,桶的数量通常选取为质数,如101、103等等。
将每个电话号码转换为一个哈希值,可以使用简单的取模运算来实现,如对电话号码取模101。
将哈希值作为索引,将电话号码存入相应的桶中。
对于哈希冲突,可以采用开放地址法、链表法等方式来解决。
开放地址法是一种解决哈希冲突的方法,它的思路是如果一个哈希值已经被占用了,就往后找一个空闲的位置,直到找到空闲位置为止。
线性探测是最简单的开放地址法,它的步骤如下:
如果该位置已经被占用了,就顺序往后找下一个位置,直到找到一个空闲位置或者查找了整个桶数组。
如果整个桶数组都被查找了一遍,但是没有找到空闲位置,那么就认为哈希表已经满了。
二次探测是一种改进的开放地址法,它的步骤如下:
如果该位置已经被占用了,就计算下一个探测点的位置,可以使用如下公式:$hash_i = (hash(key) + i^2) % tableSize$,其中i表示进行了几次探测。
如果所有的探测点都被占用,那么就认为哈希表已经满了。
链表法是另一种常用的解决哈希冲突的方法,它的思路是当多个键值映射到同一个位置时,将这些键值放在同一个链表中。
下面是使用Python实现电话目录的示例代码,其中使用开放地址法进行哈希冲突的解决。
class PhoneBook:
def __init__(self, size=101):
self.size = size
self.table = [None] * self.size
def _hash(self, key):
return hash(key) % self.size
def insert(self, key, value):
h = self._hash(key)
i = 0
while i < self.size and self.table[h] is not None:
h = (h + 1) % self.size
i += 1
if i == self.size:
raise Exception('Hash table is full')
self.table[h] = (key, value)
def search(self, key):
h = self._hash(key)
i = 0
while i < self.size and self.table[h] is not None:
if self.table[h][0] == key:
return self.table[h][1]
h = (h + 1) % self.size
i += 1
return None
def delete(self, key):
h = self._hash(key)
i = 0
while i < self.size and self.table[h] is not None:
if self.table[h][0] == key:
self.table[h] = None
return
h = (h + 1) % self.size
i += 1
raise KeyError(key)
哈希表是一种高效的数据结构,可以用于实现电话目录、词频统计、缓存等等场景。在使用哈希表时,需要注意哈希冲突的解决方法以及哈希函数的选择。