Python 中的哈希表 - 冲突、负载因子和再哈希2024 年 8 月 29 日 | 阅读 12 分钟 引言在本教程中,我们将学习 Python 中的哈希表,包括冲突、负载因子和再哈希。哈希表是一种索引数据结构。它以键值对的形式存储数据。在这种数据结构中,数据存储在特殊的索引中。哈希函数创建索引。这个哈希函数可以是内置的或生成的,它使用特定的键来创建索引以存储数据。键必须是不可变的且唯一的。通过哈希,插入、删除和搜索操作的平均时间复杂度接近常数 O(1),最坏情况下也可能是 O(n) 或 O(1)。Python 中的哈希表包含一些用于设置值、获取值和从索引中删除值的函数。这些函数如下:
哈希 - 哈希函数此函数将键转换为一个小值,用作哈希表中的索引。键值可以是整数或字符串。哈希函数有两种类型,如下所示: a. 内置哈希函数 在内置哈希函数中,hash() 函数返回对象的哈希值。 b. 用户定义的哈希函数 开发人员创建用户定义的哈希函数。 冲突冲突是 Python 中哈希表的一部分。当您想将数据插入哈希表,但其他键已经占用了该索引时,就会发生冲突。一个好的哈希表的特点是冲突数量较少。通过使用两种方法,我们可以轻松避免冲突,如下所示: 1. 分离链接分离链接也称为开放哈希。如果两个键的哈希值相同,则将第二个键的数据以链式模式添加到第一个键的末尾并继续。链接可以借助其他数据结构完成,例如链表、列表或自平衡 BST(AVL 树、红黑树)。连接中的大多数键都分配在哈希表外部。以下数据库的访问时间值对于链表和列表范围从 O(1) 到 O(n),对于树范围从 O(logn)。 程序代码 现在我们给出 Python 中开放哈希或分离链接的程序代码,如下所示: 输出 现在,我们编译并运行上述程序。结果如下: True False 5 2 2 2. 开放寻址开放寻址也称为闭合哈希。如果另一个键分配了索引,它将检查哈希表中的下一个可用空间以给出新的键值。探测可以通过多种方式完成。探测有三种类型:线性探测、二次探测和双重哈希。 a. 线性探测 循环地,搜索从起始索引到前一个索引以查找下一个空槽。线性探测中的缓存性能非常好,这是一个优势。但也有一个缺点。线性探测的缺点是会发生主要聚类和次要聚类。 b. 二次探测 在二次探测中,以二次方式搜索索引中的下一个空槽。因此,需要第 n 次迭代才能找到第 (n²) 个槽。没有主要聚类,这是二次探测的一个优势。但也有一个缺点。二次探测的缺点是会发生次要聚类和非常差的缓存性能。 c. 双重哈希 在双重哈希中,我们使用第二个哈希函数来查找索引的下一个可用空间。此索引是从第一个哈希函数获得的。没有任何主要和次要聚类,这是双重哈希的一个优势。但也有一个缺点。双重哈希的缺点是缓存性能非常差。 什么是聚类?在聚类中,当不同的数据(键)放置在相同的哈希索引时,连续的键或索引会迅速包含在内。 负载因子负载因子定义为 (m/n)。其中,m 表示在增加哈希表大小之前可以在哈希表中找到的元素数量,n 表示哈希表的大小。负载因子是一个参数,它决定何时增加哈希表大小,以便以尽可能低的时间复杂度 O(1) 进行查找和添加。Java 中哈希表的默认负载因子是哈希表大小的 0.75f。当当前负载因子超过预定义负载时,哈希表的大小必须加倍。负载因子的一些步骤如下:
Rehash负载因子是再哈希的一部分。它是一种特殊的避免冲突并使时间复杂度达到 O(1) 的方法。当哈希表大小达到或超过某个称为负载因子的点时,这是增加或加倍哈希表大小的过程。进行再哈希是为了在哈希表满时减少从哈希表访问元素的难度。 访问哈希表元素的时间复杂度在最佳情况下为 O(1)。在这里,所有键值对都在一个索引中,在最坏情况下为 O(n),当所有键值对都存储在一个索引中。索引中项目按顺序输入。因此,重复操作是为了减少访问时间并计算哈希表中的所有键点。如果哈希表中的点数超过起始指针或哈希表的大小,请使用重用方法。再哈希是根据哈希表的负载因子完成的。它将决定何时增加哈希表大小。 为什么哈希表需要再哈希?为了防止冲突,哈希表需要再哈希。它还保持数据结构的效率。如果将元素添加到哈希表中,负载因子会增加。负载因子是内容数量与桶数量之比。当它大于某个阈值(通常设置为 0.75)时,由于冲突增加,哈希表变得不可用。为了避免这种情况,可以修改哈希表。此外,内容在新的桶中重新创建,从而降低了负载和冲突。这被称为再哈希。它可能需要时间和空间,但它应该使哈希表高效。再哈希时,您需要从哈希函数中检查索引,以将旧哈希表中的内容添加到新哈希表中。如果哈希函数使用哈希表的大小来查找索引,则在再哈希时始终会考虑新的大小。 再哈希的步骤是什么?再哈希可以通过以下步骤完成:
例如,假设一个 5 维哈希表,哈希函数是 key % size (key % 5)。我们需要向哈希表添加 5 个元素,例如 11、12、13、14 和 15,这使得时间复杂度为 O(1)。0.75 是初始负载因子。 所以,_hash(key) 等于
程序代码 现在我们给出 Python 中再哈希哈希表的程序代码,如下所示: 输出 现在,我们编译并运行上述程序。结果如下: The Hash Map is created The total number of pairs in the Map: 0 The Map size is: 7 Default Load Factor is: 0.75 Pair(" 1 ", " Java ") insertion is successfully done. Current Load factor = 0.14285714285714285 The number of pairs in the Map: 1 The Map size is: 7 Current HashMap: key = " 1 ", val = Java Pair(" 2 ", " Tpoint ") insertion is successfully done. Current Load factor = 0.2857142857142857 The number of pairs in the Map: 2 The Map size is: 7 Current HashMap: key = " 1 ", val = Java key = " 2 ", val = Tpoint Pair(" 3 ", " Is ") insertion is successfully done. Current Load factor = 0.42857142857142855 The number of pairs in the Map: 3 The Map size is: 7 Current HashMap: key = " 1 ", val = Java key = " 2 ", val = Tpoint key = " 3 ", val = Is Pair(" 4 ", " A ") insertion is successfully done. Current Load factor = 0.5714285714285714 The number of pairs in the Map: 4 The Map size is: 7 Current HashMap: key = " 1 ", val = Java key = " 2 ", val = Tpoint key = " 3 ", val = Is key = " 4 ", val = A Pair(" 5 ", " Online ") insertion is successfully done. Current Load factor = 0.7142857142857143 The number of pairs in the Map: 5 The Map size is: 7 Current HashMap: key = " 1 ", val = Java key = " 2 ", val = Tpoint key = " 3 ", val = Is key = " 4 ", val = A key = " 5 ", val = Online Pair(" 6 ", " Learning ") insertion is successfully done. Current Load factor = 0.8571428571428571 0.8571428571428571 is greater than 0.75 Therefore, Rehashing will be done. ***Rehashing Started*** ***Rehashing Ended*** The new Map size is: 14 The number of pairs in the Map: 0 The Map size is: 14 Current HashMap: key = " 1 ", val = Java key = " 2 ", val = Tpoint key = " 3 ", val = Is key = " 4 ", val = A key = " 5 ", val = Online key = " 6 ", val = Learning Pair(" 7 ", " Website ") insertion is successfully done. Current Load factor = 0.07142857142857142 The number of pairs in the Map: 1 The Map size is: 14 Current HashMap: key = " 1 ", val = Java key = " 2 ", val = Tpoint key = " 3 ", val = Is key = " 4 ", val = A key = " 5 ", val = Online key = " 6 ", val = Learning key = " 7 ", val = Website 下一个主题如何将图像转换为 NumPy 数组? |
我们请求您订阅我们的新闻通讯以获取最新更新。