哈希映射是索引数据结构。散列映射使用散列函数来计算带有键的索引到桶或槽数组中。它的值被映射到具有相应索引的桶。密钥是唯一且不可变的。将哈希图想象成一个柜子,柜子上有抽屉,里面存放的东西都有标签。例如,存储用户信息——以电子邮件为键,我们可以将与该用户对应的值(如名字、姓氏等)映射到一个存储桶。
哈希函数是实现哈希映射的核心。它接收键并将其转换为存储桶列表中存储桶的索引。理想的散列应该为每个键生成不同的索引。但是,可能会发生冲突。当散列给出现有索引时,我们可以通过附加列表或重新散列来简单地使用多个值的存储桶。
在Python,字典是哈希映射的示例。我们将从头开始看到哈希映射的实现,以了解如何构建和自定义此类数据结构以优化搜索。
哈希映射设计将包括以下功能:
- set_val(key, value):将键值对插入到哈希映射中。如果哈希映射中已存在该值,则更新该值。
- get_val(key):返回指定键映射到的值,如果此映射不包含键的映射,则返回“未找到记录”。
- delete_val(key):如果哈希映射包含键的映射,则删除特定键的映射。
下面是实现。
Python3
class HashTable:
# Create empty bucket list of given size
def __init__(self, size):
self.size = size
self.hash_table = self.create_buckets()
def create_buckets(self):
return [[] for _ in range(self.size)]
# Insert values into hash map
def set_val(self, key, val):
# Get the index from the key
# using hash function
hashed_key = hash(key) % self.size
# Get the bucket corresponding to index
bucket = self.hash_table[hashed_key]
found_key = False
for index, record in enumerate(bucket):
record_key, record_val = record
# check if the bucket has same key as
# the key to be inserted
if record_key == key:
found_key = True
break
# If the bucket has same key as the key to be inserted,
# Update the key value
# Otherwise append the new key-value pair to the bucket
if found_key:
bucket[index] = (key, val)
else:
bucket.append((key, val))
# Return searched value with specific key
def get_val(self, key):
# Get the index from the key using
# hash function
hashed_key = hash(key) % self.size
# Get the bucket corresponding to index
bucket = self.hash_table[hashed_key]
found_key = False
for index, record in enumerate(bucket):
record_key, record_val = record
# check if the bucket has same key as
# the key being searched
if record_key == key:
found_key = True
break
# If the bucket has same key as the key being searched,
# Return the value found
# Otherwise indicate there was no record found
if found_key:
return record_val
else:
return "No record found"
# Remove a value with specific key
def delete_val(self, key):
# Get the index from the key using
# hash function
hashed_key = hash(key) % self.size
# Get the bucket corresponding to index
bucket = self.hash_table[hashed_key]
found_key = False
for index, record in enumerate(bucket):
record_key, record_val = record
# check if the bucket has same key as
# the key to be deleted
if record_key == key:
found_key = True
break
if found_key:
bucket.pop(index)
return
# To print the items of hash map
def __str__(self):
return "".join(str(item) for item in self.hash_table)
hash_table = HashTable(50)
# insert some values
hash_table.set_val('gfg@example.com', 'some value')
print(hash_table)
print()
hash_table.set_val('portal@example.com', 'some other value')
print(hash_table)
print()
# search/access a record with key
print(hash_table.get_val('portal@example.com'))
print()
# delete or remove a value
hash_table.delete_val('portal@example.com')
print(hash_table)
输出:
时间复杂度:
内存索引访问需要固定时间,而散列需要固定时间。因此,哈希映射的搜索复杂度也是常数时间,即 O(1)。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live