Skip to content

Commit

Permalink
[notes][19_hashtable] conflict.
Browse files Browse the repository at this point in the history
  • Loading branch information
Liam0205 committed Dec 1, 2018
1 parent d8e52f1 commit 512c9b7
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
Empty file added notes/19_hashtable/.gitkeep
Empty file.
53 changes: 53 additions & 0 deletions notes/19_hashtable/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# 散列表

核心:散列表的效率并不总是 $O(1)$,仅仅是在理论上能达到 $O(1)$。实际情况中,恶意攻击者可以通过精心构造数据,使得散列表的性能急剧下降。

如何设计一个工业级的散列表?

## 散列函数

* 不能过于复杂——避免散列过程耗时
* 散列函数的结果要尽可能均匀——最小化散列冲突

## 装载因子过大怎么办

动态扩容。涉及到 rehash,效率可能很低。

![](https://static001.geekbang.org/resource/image/67/43/67d12e07a7d673a9c1d14354ad029443.jpg)

如何避免低效扩容?

——将 rehash 的步骤,均摊到每一次插入中去:

* 申请新的空间
* 不立即使用
* 每次来了新的数据,往新表插入数据
* 同时,取出旧表的一个数据,插入新表

![](https://static001.geekbang.org/resource/image/6d/cb/6d6736f986ec4b75dabc5472965fb9cb.jpg)

## 解决冲突

开放寻址法,优点:

* 不需要额外空间
* 有效利用 CPU 缓存
* 方便序列化

开放寻址法,缺点:

* 查找、删除数据时,涉及到 `delete` 标志,相对麻烦
* 冲突的代价更高
* 对装载因子敏感

链表法,优点:

* 内存利用率较高——链表的优点
* 对装载因子不敏感

链表法,缺点:

* 需要额外的空间(保存指针)
* 对 CPU 缓存不友好

——将链表改造成更高效的数据结构,例如跳表、红黑树

0 comments on commit 512c9b7

Please sign in to comment.