This commit is contained in:
krahets
2023-08-29 20:57:15 +08:00
parent 638312fdb1
commit 9f30ce7260
29 changed files with 95 additions and 58 deletions
+12 -4
View File
@@ -6,7 +6,7 @@ comments: true
上节提到,**通常情况下哈希函数的输入空间远大于输出空间**,因此理论上哈希冲突是不可避免的。比如,输入空间为全体整数,输出空间为数组容量大小,则必然有多个整数映射至同一数组索引。
哈希冲突会导致查询结果错误,严重影响哈希表的可用性。为解决该问题,我们可以每当遇到哈希冲突时就进行哈希表扩容,直至冲突消失为止。此方法简单粗暴且有效,但效率太低,因为哈希表扩容需要进行大量的数据搬运与哈希值计算。为了提升效率,我们可以采用以下思路
哈希冲突会导致查询结果错误,严重影响哈希表的可用性。为解决该问题,我们可以每当遇到哈希冲突时就进行哈希表扩容,直至冲突消失为止。此方法简单粗暴且有效,但效率太低,因为哈希表扩容需要进行大量的数据搬运与哈希值计算。为了提升效率,我们可以采用以下策略
1. 改良哈希表数据结构,**使得哈希表可以在存在哈希冲突时正常工作**。
2. 仅在必要时,即当哈希冲突比较严重时,才执行扩容操作。
@@ -168,6 +168,16 @@ comments: true
HashMapChaining() : size(0), capacity(4), loadThres(2.0 / 3), extendRatio(2) {
buckets.resize(capacity);
}
/* 析构方法 */
~HashMapChaining() {
for (auto &bucket : buckets) {
for (Pair *pair : bucket) {
// 释放内存
delete pair;
}
}
}
/* 哈希函数 */
int hashFunc(int key) {
@@ -1148,9 +1158,7 @@ comments: true
}
```
!!! tip
当链表很长时,查询效率 $O(n)$ 很差,**此时可以将链表转换为“AVL 树”或“红黑树”**,从而将查询操作的时间复杂度优化至 $O(\log n)$ 。
值得注意的是,当链表很长时,查询效率 $O(n)$ 很差。**此时可以将链表转换为“AVL 树”或“红黑树”**,从而将查询操作的时间复杂度优化至 $O(\log n)$ 。
## 6.2.2   开放寻址
+3 -1
View File
@@ -4,6 +4,8 @@ comments: true
# 6.4   小结
### 1.   重点回顾
- 输入 `key` ,哈希表能够在 $O(1)$ 时间内查询到 `value` ,效率非常高。
- 常见的哈希表操作包括查询、添加键值对、删除键值对和遍历哈希表等。
- 哈希函数将 `key` 映射为数组索引,从而访问对应桶并获取 `value`
@@ -18,7 +20,7 @@ comments: true
- 常见的哈希算法包括 MD5、SHA-1、SHA-2 和 SHA3 等。MD5 常用于校验文件完整性,SHA-2 常用于安全应用与协议。
- 编程语言通常会为数据类型提供内置哈希算法,用于计算哈希表中的桶索引。通常情况下,只有不可变对象是可哈希的。
## 6.4.1   Q & A
### 2.   Q & A
!!! question "哈希表的时间复杂度为什么不是 $O(n)$ ?"