概念
哈希表是一种数据结构,通过哈希函数来组织数据,以支持快速插入和搜索。
哈希表的关键思想是使用哈希函数将键映射到存储桶。更确切地说,
- 当我们插入一个新的键时,哈希函数将决定该键应该分配到哪个桶中,并将该键存储在相应的桶中;
- 当我们想要搜索一个键时,哈希表将使用相同的哈希函数来查找对应的桶,并只在特定的桶中进行搜索。
哈希冲突
理想情况下,我们设计的哈希表可以将键和桶一一映射,然而很难实现。那要解决哈希冲突,我们可以将桶的结构设计成数组或者链表,如此就可以将冲突的键(或键值对)有组织地存储进来。
哈希表的应用一:哈希集合
哈希集合即将一个集合用哈希表的数据结构形式存放。
下面是用数组方式创建的哈希集合:
class MyHashSet:
def __init__(self):
self.size = 20
self.buckets = [[] for i in range(self.size)] # 列表实现
def hash(self, key):
return key % self.size
def add(self, key: int) -> None:
index = self.hash(key)
if not self.contains(key):
self.buckets[index].append(key)
def remove(self, key: int) -> None:
index = self.hash(key)
if self.contains(key):
self.buckets[index].remove(key)
def contains(self, key: int) -> bool:
index = self.hash(key)
if key in self.buckets[index]:
return True
else:
return False
# Your MyHashSet object will be instantiated and called as such:
# obj = MyHashSet()
# obj.add(key)
# obj.remove(key)
# param_3 = obj.contains(key)
用数组方式存储桶里的数据,当对该桶里的数据进行插入或搜索时,和顺序表的复杂度一样,是O(N),而为了加快插入和搜索,我们可以将桶设计成链表。
哈希表的应用二:哈希映射
哈希映射和哈希集合类似,只不过桶里存储的是键值对。
下面是数组方式创建的哈希映射:
class MyHashMap:
def __init__(self):
self.size = 20
self.buckets = [[] for i in range(self.size)]
def hash(self, key):
return key % self.size
def put(self, key: int, value: int) -> None:
index = self.hash(key)
for item in self.buckets[index]:
if item[0] == key:
item[1] = value
return
tmp_list = [key, value]
self.buckets[index].append(tmp_list)
def get(self, key: int) -> int:
index = self.hash(key)
for item in self.buckets[index]:
if item[0] == key:
return item[1]
return -1
def remove(self, key: int) -> None:
index = self.hash(key)
for item in self.buckets[index]:
if item[0] == key:
self.buckets[index].remove(item)
# Your MyHashMap object will be instantiated and called as such:
# obj = MyHashMap()
# obj.put(key,value)
# param_2 = obj.get(key)
# obj.remove(key)