File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 2222
2323![ img] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20200702071922.png )
2424
25- - [ 算法概述 ] ( docs/overview .md )
26- - [ 复杂度分析] ( docs/复杂度分析.md )
27- - [ 数组和链表] ( docs/数组和链表.md )
28- - [ 栈和队列] ( docs/栈和队列.md )
25+ - [ 数据结构和算法指南 ] ( docs/数据结构和算法指南 .md )
26+ - [ 复杂度分析] ( docs/复杂度分析.md ) - 关键词: ** ` 时间复杂度 ` ** 、 ** ` 空间复杂度 ` ** 、 ** ` 大 O 表示法 ` ** 、 ** ` 复杂度量级 ` **
27+ - [ 数组和链表] ( docs/数组和链表.md ) - 关键词: ** ` 线性表 ` ** 、 ** ` 一维数组 ` ** 、 ** ` 多维数组 ` ** 、 ** ` 随机访问 ` ** 、 ** ` 单链表 ` ** 、 ** ` 双链表 ` ** 、 ** ` 循环链表 ` **
28+ - [ 栈和队列] ( docs/栈和队列.md ) - 关键词: ** ` 先进后出 ` ** 、 ** ` 后进先出 ` ** 、 ** ` 循环队列 ` **
2929- [ 线性表的查找] ( docs/线性表的查找.md )
3030- [ 线性表的排序] ( docs/线性表的排序.md )
3131- [ 跳表] ( docs/跳表.md )
File renamed without changes.
Original file line number Diff line number Diff line change @@ -6,11 +6,11 @@ B+树是在二叉查找树的基础上进行了改造:树中的节点并不存
66
77
88
9- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220311092926.jpg )
9+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220311092926.jpg )
1010
1111改造之后,如果我们要求某个区间的数据。我们只需要拿区间的起始值,在树中进行查找,当查找到某个叶子节点之后,我们再顺着链表往后遍历,直到链表中的结点数据值大于区间的终止值为止。所有遍历到的数据,就是符合区间值的所有数据。
1212
13- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220311092929.jpg )
13+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220311092929.jpg )
1414
1515但是,我们要为几千万、上亿的数据构建索引,如果将索引存储在内存中,尽管内存访问的速度非常快,查询的效率非常高,但是,占用的内存会非常多。
1616
Original file line number Diff line number Diff line change @@ -17,7 +17,7 @@ LSM 树就是根据这个思路设计了这样一个机制:当数据写入时
1717
1818可以参考两个有序链表归并排序的过程,将 C0 树和 C1 树的所有叶子节点中存储的数据,看作是两个有序链表,那滚动合并问题就变成了我们熟悉的两个有序链表的归并问题。不过由于涉及磁盘操作,那为了提高写入效率和检索效率,我们还需要针对磁盘的特性,在一些归并细节上进行优化。
1919
20- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220316105440.png )
20+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220316105440.png )
2121
2222由于磁盘具有顺序读写效率高的特性,因此,为了提高 C1 树中节点的读写性能,除了根节点以外的节点都要尽可能地存放到连续的块中,让它们能作为一个整体单位来读写。这种包含多个节点的块就叫作多页块(Multi-Pages Block)。
2323
@@ -29,7 +29,7 @@ LSM 树就是根据这个思路设计了这样一个机制:当数据写入时
2929
3030第四步,重复第三步,直到遍历完 C0 树和 C1 树的所有叶子节点,并将所有的归并结果写入到磁盘。这个时候,我们就可以同时删除 C0 树和 C1 树中被处理过的叶子节点。这样就完成了滚动归并的过程。
3131
32- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220316110736.png )
32+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220316110736.png )
3333
3434### LSM 树是如何检索
3535
@@ -58,7 +58,7 @@ WAL 技术保存和恢复数据的具体步骤如下:
58583 . 系统会周期性地检查内存中的数据是否都被处理完了(比如,被删除或者写入磁盘),并且生成对应的检查点(Check Point)记录在磁盘中。然后,我们就可以随时删除被处理完的数据了。这样一来,log 文件就不会无限增长了。
59594 . 系统崩溃重启,我们只需要从磁盘中读取检查点,就能知道最后一次成功处理的数据在 log 文件中的位置。接下来,我们就可以把这个位置之后未被处理的数据,从 log 文件中读出,然后重新加载到内存中。
6060
61- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220316104837.png )
61+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220316104837.png )
6262
6363## 参考资料
6464
Load Diff This file was deleted.
Original file line number Diff line number Diff line change 2020
2121** 哈希表用的是数组支持按照下标随机访问数据的特性,所以哈希表其实就是数组的一种扩展,由数组演化而来。可以说,如果没有数组,就没有哈希表** 。
2222
23- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320201844.png )
23+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320201844.png )
2424
2525哈希表通过散列函数把元素的键值映射为下标,然后将数据存储在数组中对应下标的位置。按照键值查询元素时,用同样的散列函数,将键值转化数组下标,从对应的数组下标的位置取数据。
2626
8080
8181** 线性探测** (Linear Probing):当我们往哈希表中插入数据时,如果某个数据经过散列函数散列之后,存储位置已经被占用了,我们就从当前位置开始,依次往后查找,看是否有空闲位置,直到找到为止。
8282
83- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220310110920.jpg )
83+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220310110920.jpg )
8484
8585对于使用线性探测法解决冲突的哈希表,删除操作稍微有些特别。我们不能单纯地把要删除的元素设置为空。这是为什么呢?在查找的时候,一旦我们通过线性探测方法,找到一个空闲位置,我们就可以认定哈希表中不存在这个数据。但是,如果这个空闲位置是我们后来删除的,就会导致原来的查找算法失效。本来存在的数据,会被认定为不存在。这个问题如何解决呢?
8686
8787我们可以将删除的元素,特殊标记为 deleted。当线性探测查找的时候,遇到标记为 deleted 的空间,并不是停下来,而是继续往下探测。
8888
89- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220310111103.jpg )
89+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220310111103.jpg )
9090
9191线性探测法其实存在很大问题。当哈希表中插入的数据越来越多时,散列冲突发生的可能性就会越来越大,空闲位置会越来越少,线性探测的时间就会越来越久。极端情况下,我们可能需要探测整个哈希表,所以最坏情况下的时间复杂度为 O(n)。同理,在删除和查找时,也有可能会线性探测整张哈希表,才能找到要查找或者删除的数据。
9292
9898
9999** 基于链表的散列冲突处理方法比较适合存储大对象、大数据量的哈希表,而且,比起开放寻址法,它更加灵活,支持更多的优化策略,比如用红黑树代替链表** 。
100100
101- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220310111320.jpg )
101+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220310111320.jpg )
102102
103103当插入的时候,我们只需要通过散列函数计算出对应的散列槽位,将其插入到对应链表中即可,所以插入的时间复杂度是 O(1)。当查找、删除一个元素时,我们同样通过散列函数计算出对应的槽,然后遍历链表查找或者删除。那查找或删除操作的时间复杂度是多少呢?
104104
Original file line number Diff line number Diff line change 2222
2323如果图的边没有方向性,则被成为无向图。
2424
25- ![ ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220314093554.jpg )
25+ ![ img ] ( https://raw.githubusercontent.com/dunwu/images/dev/snap/20220314093554.jpg )
2626
2727## 图的基本操作
2828
You can’t perform that action at this time.
0 commit comments