📜  数据结构和算法-哈希表(1)

📅  最后修改于: 2023-12-03 15:26:09.673000             🧑  作者: Mango

数据结构和算法-哈希表

简介

哈希表(Hash Table),也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做哈希函数,存放记录的数组叫做哈希表。

哈希表的实现使用数组和链表的数据结构,它的操作可以分为插入、查找、删除等基本操作。哈希表的优点是查找速度快,时间复杂度通常为 O(1),是数组和链表等数据结构无法比拟的。

哈希函数

哈希函数是哈希表实现的关键,它将每个关键字映射到哈希表中的一个位置。一个好的哈希函数需要满足以下几个条件:

  1. 散列函数计算简单,高效。
  2. 散列函数散列性好,减少冲突。
  3. 均匀分布性好,增加数据分布均衡。

常用的哈希函数有以下几种:

直接定址法

直接定址法是最简单的哈希函数,它直接将关键字作为哈希值。例如,对于一个整数关键字,哈希函数可以是 $h(key)=key$。

直接定址法的缺点是它的散列性非常依赖关键字本身,如果关键字分布极其不均匀,容易产生冲突。

除留余数法

除留余数法是将关键字除以某个数,取余数作为哈希值。例如,对于一个整数关键字,哈希函数可以是 $h(key)=key % p$,其中 $p$ 是一个质数。

除留余数法实现简单,散列性较好,但不能使用长度与 $p$ 相近的关键字,否则容易导致冲突。

平方取中法

平方取中法是先将关键字平方,然后取中间的几位作为哈希值。例如,对于一个四位十进制数关键字 $6954$,哈希函数可以是 $h(key)=middle(6954^2)$,其中 $middle$ 是取中间两位的函数。

平方取中法较好地解决了直接定址法和除留余数法的缺点,但实现起来稍微麻烦一些。

随机数法

随机数法是使用一个随机数当作哈希函数,例如,对于一个整数关键字,哈希函数可以是 $h(key)=random()$。随机函数需要足够随机,才能达到较好的散列效果。

随机数法实现简单,散列性好,但需要较大的空间存储随机数。

实现

下面是一个简单的哈希表实现,包括哈希函数和基本操作:插入、查找、删除。

class Node:
    def __init__(self, key, value):
        self.key = key   # 关键字
        self.value = value # 值
        self.next = None  # 指向下一个节点

class HashTable:
    def __init__(self, size=1000):
        self.size = size  # 哈希表大小
        self.table = [None] * size  # 哈希表数组

    def _hash(self, key):
        """哈希函数:通过取余方法计算哈希值"""
        return hash(key) % self.size

    def put(self, key, value):
        """插入"""
        h = self._hash(key)
        if self.table[h] is None:
            self.table[h] = Node(key, value)
            return
        node = self.table[h]
        while node.next is not None:
            node = node.next
        node.next = Node(key, value)

    def get(self, key):
        """查找"""
        h = self._hash(key)
        node = self.table[h]
        while node is not None:
            if node.key == key:
                return node.value
            node = node.next
        return None

    def remove(self, key):
        """删除"""
        h = self._hash(key)
        node = self.table[h]
        if node is None:
            return
        if node.key == key:
            self.table[h] = node.next
            return
        while node.next is not None:
            if node.next.key == key:
                node.next = node.next.next
                return
            node = node.next
总结

哈希表是一种高效的数据结构,可用于快速查找数据。然而,哈希函数的实现是一门深奥的学问,有一些关键的问题需要解决,例如哈希值的分布均衡、冲突处理等。在实际应用中,需要根据具体情况选择哈希函数的适当实现,以达到最佳的效果。