实现Hash表(一)----手写一个简单hash表

什么是hash表?

hash表是一种数据结构,可以快速实现插入和查找。

一般是通过(key,value) 的方式来进行存储,例如python中的字典就是hash表的一个很好的例子。

设计原理

举个例子:

1.创建一个长度为4096的list,其中的元素都为None

2.插入(‘a’,1)这个数据 ---- 我们要知道应该把元素插在哪里

​ 首先要获取key的hash值,再根据这个hash值得到索引,我们这里采用最简单的获取hash值的算法。

​ 我们假设对应hash值的算法就是每个字母对应的ASCII码值相加

​ 通过hash值获得数据在list中的索引,这里可以通过取余数的方式进行,保证不会越界访问数组

​ 例如 :hash值为 1 对应的索引就为1(1%4096=1)

​ 4098对应的索引就为2(4098%4096=2)

3.获取到索引index之后,令 list[index]=(key,value)

​ 这样就完成了插入操作

​ 查找时,只要知道key,计算出对应的索引,就可以直接通过访问list获取value了。

​ (因为list的存储是连续的,只要知道了第一个元素地址,再知道index,就可以直接算出来偏移量进行访问,不用进行遍历,复杂度大大降低,也就是O(1)的复杂度~)

抽象点的步骤:

  1. 创建一个长度为n的数组
  2. 计算key对应的hash值
  3. 完成插入/查找

python的实现

MAX_HASH_TABLE_SIZE = 4096

def get_index(data_list, a_string):
    # 存储hash值
    result = 0

    for a_character in a_string:
        # 获取ASCII码
        a_number = ord(a_character)
        # 更新hash值
        result += a_number

    # 通过取余数获取索引值
    list_index = result % len(data_list)
    return list_index

if __name__ == '__main__':
    data_list = [None] * MAX_HASH_TABLE_SIZE
    # 插入
    # 方法一
    key, value = 'test1', '7878787878'
    idx = get_index(data_list, key)
    data_list[idx] = (key, value)
    # 方法二
    data_list[get_index(data_list, 'test2')] = ('test2', '9595949494')
    
    # 测试是否成功插入 
    # [1]是因为存储的是key,value 要访问value
    print(data_list[get_index(data_list, 'test1')][1]=='7878787878')
    print(data_list[get_index(data_list, 'test2')][1]=='9595949494')

可以将上述代码封装一下,用类来实现我们的hash表

MAX_HASH_TABLE_SIZE = 4096

def get_index(data_list, a_string):
    # 存储hash值
    result = 0

    for a_character in a_string:
        # 获取ASCII码
        a_number = ord(a_character)
        # 更新hash值
        result += a_number

    # 通过取余数获取索引值
    list_index = result % len(data_list)
    return list_index

class MyHashTable:
    def __init__(self, max_size=MAX_HASH_TABLE_SIZE):
        self.data_list = [None] * max_size

    def insert(self, key, value):
        """Insert a new key-value pair"""
        index = get_index(self.data_list, key)
        self.data_list[index] = (key, value)

    def find(self, key):
        """Find the value associated with a key"""
        index = get_index(self.data_list, key)
        key_value = self.data_list[index]
        if key_value is None:
            return key_value
        else:
            return key_value[1]

    def update(self, key, value):
        """Change the value associated with a key"""
        index = get_index(self.data_list, key)
        self.data_list[index] = (key, value)

    def list_all(self):
        """List all the keys"""
        return [key_value[0] for key_value in self.data_list if key_value is not None]
    
if __name__ == '__main__':
    basic_table = MyHashTable(1024)
    print(len(basic_table.data_list) == 1024)
    # Insert some values
    basic_table.insert('test1', '9999999999')
    basic_table.insert('test2', '8888888888')

    # Find a value
    print(basic_table.find('test2') == '8888888888')

    # Update a value
    basic_table.update('test1', '7777777777')

    # Check the updated value
    print(basic_table.find('test1') == '7777777777')

    # Get the list of keys
    print(basic_table.list_all() == ['test1', 'test2'])

总结

这样我们就自己实现了最简单的hash表,但是细细想想,其实问题还是很多的,例如:当两个key映射的index是一样的的时候,该如何处理这种冲突问题呢?

具体的处理方法参见:实现Hash表(二)----处理index冲突问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值