📅  最后修改于: 2023-12-03 15:10:16.825000             🧑  作者: Mango
散列(Hash)是一种将输入数据映射到一个固定大小的数据集合中的技术。在散列表(Hash Table)中,使用散列函数将数据元素的键(Key)映射到存储该键所对应的值(Value)的位置。
散列表有两种实现方式:链表法和开放寻址法。开放寻址法包含三种方法:线性探测、二次探测和双重散列。
其中,本篇文章将介绍的是散列设置3(开放寻址)中的线性探测法。该方法在发生碰撞(Collision)时,在散列表中进行线性探测,直到找到空闲位置为止。每个位置都按照固定的步长增量(通常为1)来探测下一个位置。
当散列表容量不足时,需要进行扩容(Rehash)。扩容后,会新建一个更大的散列表,并将原有的键值对重新散列到新散列表中。同时,扩容操作需要重新计算散列函数,以便新散列表能够更好的散列输入数据。
下面是一个使用线性探测法实现散列表,以及插入、查找、删除操作的示例代码:
class HashTable:
def __init__(self, capacity):
"""
初始化一个容量为 capacity 的散列表
"""
self.capacity = capacity
self.size = 0
self.keys = [None] * capacity
self.values = [None] * capacity
def hash(self, key):
"""
散列函数:将键映射到散列表中的位置
"""
return hash(key) % self.capacity
def rehash(self):
"""
扩容操作:创建一个新的散列表,将原有的键值对重新散列到新散列表中
"""
new_capacity = 2 * self.capacity
new_keys = [None] * new_capacity
new_values = [None] * new_capacity
for i in range(self.capacity):
if self.keys[i] is not None:
index = self.hash(self.keys[i])
while new_keys[index] is not None:
index = (index + 1) % new_capacity
new_keys[index] = self.keys[i]
new_values[index] = self.values[i]
self.capacity = new_capacity
self.keys = new_keys
self.values = new_values
def put(self, key, value):
"""
插入键值对
"""
if self.size == self.capacity:
self.rehash()
index = self.hash(key)
while self.keys[index] is not None:
if self.keys[index] == key:
self.values[index] = value # 已存在,更新键值
return
index = (index + 1) % self.capacity
self.keys[index] = key
self.values[index] = value
self.size += 1
def get(self, key):
"""
获取键对应的值
"""
index = self.hash(key)
while self.keys[index] is not None:
if self.keys[index] == key:
return self.values[index]
index = (index + 1) % self.capacity
return None
def delete(self, key):
"""
删除键值对
"""
index = self.hash(key)
while self.keys[index] is not None:
if self.keys[index] == key:
self.keys[index] = None
self.values[index] = None
self.size -= 1
return
index = (index + 1) % self.capacity
以上为使用线性探测法实现散列表的基本代码。在实际应用中,需要根据具体情况确定散列函数和步长增量,以获得更好的性能表现。