This commit is contained in:
krahets
2023-11-09 05:13:48 +08:00
parent 9701430089
commit 0105644232
83 changed files with 516 additions and 509 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ comments: true
如果哈希冲突过于频繁,哈希表的性能则会急剧劣化。如图 6-8 所示,对于链地址哈希表,理想情况下键值对平均分布在各个桶中,达到最佳查询效率;最差情况下所有键值对都被存储到同一个桶中,时间复杂度退化至 $O(n)$ 。
![哈希冲突的最佳与最差情况](hash_algorithm.assets/hash_collision_best_worst_condition.png)
![哈希冲突的最佳与最差情况](hash_algorithm.assets/hash_collision_best_worst_condition.png){ class="animation-figure" }
<p align="center"> 图 6-8 &nbsp; 哈希冲突的最佳与最差情况 </p>
+3 -3
View File
@@ -17,7 +17,7 @@ comments: true
在原始哈希表中,每个桶仅能存储一个键值对。「链式地址 separate chaining」将单个元素转换为链表,将键值对作为链表节点,将所有发生冲突的键值对都存储在同一链表中。图 6-5 展示了一个链式地址哈希表的例子。
![链式地址哈希表](hash_collision.assets/hash_table_chaining.png)
![链式地址哈希表](hash_collision.assets/hash_table_chaining.png){ class="animation-figure" }
<p align="center"> 图 6-5 &nbsp; 链式地址哈希表 </p>
@@ -1333,7 +1333,7 @@ comments: true
图 6-6 展示了开放寻址(线性探测)哈希表的键值对分布。根据此哈希函数,最后两位相同的 `key` 都会被映射到相同的桶。而通过线性探测,它们被依次存储在该桶以及之下的桶中。
![开放寻址和线性探测](hash_collision.assets/hash_table_linear_probing.png)
![开放寻址和线性探测](hash_collision.assets/hash_table_linear_probing.png){ class="animation-figure" }
<p align="center"> 图 6-6 &nbsp; 开放寻址和线性探测 </p>
@@ -1341,7 +1341,7 @@ comments: true
值得注意的是,**我们不能在开放寻址哈希表中直接删除元素**。这是因为删除元素会在数组内产生一个空桶 $\text{None}$ ,而当查询元素时,线性探测到该空桶就会返回,因此在该空桶之下的元素都无法再被访问到,程序可能误判这些元素不存在。
![在开放寻址中删除元素导致的查询问题](hash_collision.assets/hash_table_open_addressing_deletion.png)
![在开放寻址中删除元素导致的查询问题](hash_collision.assets/hash_table_open_addressing_deletion.png){ class="animation-figure" }
<p align="center"> 图 6-7 &nbsp; 在开放寻址中删除元素导致的查询问题 </p>
+4 -4
View File
@@ -8,7 +8,7 @@ comments: true
如图 6-1 所示,给定 $n$ 个学生,每个学生都有“姓名”和“学号”两项数据。假如我们希望实现“输入一个学号,返回对应的姓名”的查询功能,则可以采用图 6-1 所示的哈希表来实现。
![哈希表的抽象表示](hash_map.assets/hash_table_lookup.png)
![哈希表的抽象表示](hash_map.assets/hash_table_lookup.png){ class="animation-figure" }
<p align="center"> 图 6-1 &nbsp; 哈希表的抽象表示 </p>
@@ -493,7 +493,7 @@ index = hash(key) % capacity
设数组长度 `capacity = 100`、哈希算法 `hash(key) = key` ,易得哈希函数为 `key % 100` 。图 6-2 以 `key` 学号和 `value` 姓名为例,展示了哈希函数的工作原理。
![哈希函数工作原理](hash_map.assets/hash_function.png)
![哈希函数工作原理](hash_map.assets/hash_function.png){ class="animation-figure" }
<p align="center"> 图 6-2 &nbsp; 哈希函数工作原理 </p>
@@ -1650,7 +1650,7 @@ index = hash(key) % capacity
如图 6-3 所示,两个学号指向了同一个姓名,这显然是不对的。我们将这种多个输入对应同一输出的情况称为「哈希冲突 hash collision」。
![哈希冲突示例](hash_map.assets/hash_collision.png)
![哈希冲突示例](hash_map.assets/hash_collision.png){ class="animation-figure" }
<p align="center"> 图 6-3 &nbsp; 哈希冲突示例 </p>
@@ -1658,7 +1658,7 @@ index = hash(key) % capacity
如图 6-4 所示,扩容前键值对 `(136, A)` 和 `(236, D)` 发生冲突,扩容后冲突消失。
![哈希表扩容](hash_map.assets/hash_table_reshash.png)
![哈希表扩容](hash_map.assets/hash_table_reshash.png){ class="animation-figure" }
<p align="center"> 图 6-4 &nbsp; 哈希表扩容 </p>
+1 -1
View File
@@ -7,7 +7,7 @@ icon: material/table-search
<div class="center-table" markdown>
![哈希表](../assets/covers/chapter_hashing.jpg){ width="600" }
![哈希表](../assets/covers/chapter_hashing.jpg){ class="cover-image" }
</div>