Skip to content

Commit 512c9b7

Browse files
committed
[notes][19_hashtable] conflict.
1 parent d8e52f1 commit 512c9b7

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

notes/19_hashtable/.gitkeep

Whitespace-only changes.

notes/19_hashtable/readme.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# 散列表
2+
3+
核心:散列表的效率并不总是 $O(1)$,仅仅是在理论上能达到 $O(1)$。实际情况中,恶意攻击者可以通过精心构造数据,使得散列表的性能急剧下降。
4+
5+
如何设计一个工业级的散列表?
6+
7+
## 散列函数
8+
9+
* 不能过于复杂——避免散列过程耗时
10+
* 散列函数的结果要尽可能均匀——最小化散列冲突
11+
12+
## 装载因子过大怎么办
13+
14+
动态扩容。涉及到 rehash,效率可能很低。
15+
16+
![](https://static001.geekbang.org/resource/image/67/43/67d12e07a7d673a9c1d14354ad029443.jpg)
17+
18+
如何避免低效扩容?
19+
20+
——将 rehash 的步骤,均摊到每一次插入中去:
21+
22+
* 申请新的空间
23+
* 不立即使用
24+
* 每次来了新的数据,往新表插入数据
25+
* 同时,取出旧表的一个数据,插入新表
26+
27+
![](https://static001.geekbang.org/resource/image/6d/cb/6d6736f986ec4b75dabc5472965fb9cb.jpg)
28+
29+
## 解决冲突
30+
31+
开放寻址法,优点:
32+
33+
* 不需要额外空间
34+
* 有效利用 CPU 缓存
35+
* 方便序列化
36+
37+
开放寻址法,缺点:
38+
39+
* 查找、删除数据时,涉及到 `delete` 标志,相对麻烦
40+
* 冲突的代价更高
41+
* 对装载因子敏感
42+
43+
链表法,优点:
44+
45+
* 内存利用率较高——链表的优点
46+
* 对装载因子不敏感
47+
48+
链表法,缺点:
49+
50+
* 需要额外的空间(保存指针)
51+
* 对 CPU 缓存不友好
52+
53+
——将链表改造成更高效的数据结构,例如跳表、红黑树

0 commit comments

Comments
 (0)