数据结构精讲:从原理到实战–学习笔记07
本笔记是记录学习 《数据结构精讲:从原理到实战》,作者是:蔡元楠,Google Brain资深工程师。
如有侵权,联系删除!
二叉查找树(BST)
二叉查找树(Binary Search Tree)简称 BST,具有以下特征:
-
二叉查找树是一棵二叉树,也就是说每一个节点至多有 2 个孩子,也就是 2 个子树。
-
二叉查找树的任意一个节点都比它的左子树所有节点大,同时比右子树所有节点小。
二叉查找树的搜索:
考虑到左小右大的特性,可以用递归的方式来实现搜索二叉树:
TreeNode* Search(TreeNode* root, int key) {
if (root == nullptr || root->key == key) {
return root;
}
if (root->key < key) {
return Search(root->right, key);
}
return Search(root->left, key);
}
他的搜索过程特别像binary search的搜索过程,所以时间复杂度也是O(logn)
只不过最坏情况,整棵树变成一个单链表,时间复杂度就是O(N)
平衡树
红黑树:
-
一棵二叉树,每一个节点要么是红色,要么是黑色
-
根节点一定是黑色
-
红节点不能有红孩子
-
每条从根节点到底部的路径都经过同样数量的黑节点
eg.
上述最后一条要求可理解成:让这棵树的叶子结点高度差不超过1. 也就说:节点1和6高度差最多是1,才能保证跟节点到叶子结点的路径经过同样数量的黑节点。
满足这些定义的红黑树可以被数学证明树的高度为 O(log n)。要实现一棵红黑树是非常难的,其中有许多节点插入 / 删除需要用到旋转等操作细节,我们在这一讲中无法展开讲解,可自行查阅资料学习。
B树
-
所有叶子节点的深度一样
-
非叶子节点只能存储 b - 1 到 2b - 1 个值
-
根节点最多存储 2b - 1 个值
eg. 等待完善
Log_Structure结构
在计算机存储数据结构的发展中,Log-Structured 结构的诞生为许多文件系统或者是数据库打下了坚实的基础。比如说,Google 的三驾马车之一,Bigtable 文件系统的底层存储数据结构采用的就是 Log-Structured 结构,还有大家所熟知的 MongoDB 和 HBase 这类的 NoSQL 数据库,它们的底层存储数据结构其实也是 Log-Structured 结构。
例如要统计一个视频观看次数,理论上可以使用hash表,以视频url为主键,统计次数为value。但是当并发执行时,为了保证数据完整正确,每次数据必须上锁,导致运行效率大大降低。
Log-Structured 结构,有时候也会被称作是 Append-only Sequence of Data,因为所有的写操作都会不停地添加进这个数据结构中,而不会更新原来已有的值,这也是 Log-Structured 结构的一大特性。
我们来看看在采用了 Log-Structured 结构之后,在上面的统计视频网站观看次数的应用中,底层的数据结构变成怎么样了。
假设现在网站总共有三个视频,URL 分别就是 A、B 和 C,那一个可能的数据结构图就如下图所示:
这样的数据结构其实和数组非常像,数组里的值就保存着 URL 和 1,每次有新用户观看过视频之后,就会将 URL 和 1 加到数组的结尾。在上面的例子中,我们只需要遍历一遍这个数组,然后将不同的 URL 值加起来就可以得到观看的总数,例如 A 的观看总数为 8 次,B 为 3 次,C 为 5 次。
但是在应用里会有很多的问题。比如说,一个数组不可能在内存中无限地增长下去,我们要如何处理呢?如果每次想要知道结果,就必须遍历一遍这样的数组,时间复杂度会非常高,那该怎么优化呢?平衡树是如何被应用在里面的呢?
LSM树在Apache HBase等存储系统中的应用
接上述问题:当数据不断增加后,内存中数组越来越大,这时候,我们就可以通过一种叫 Compaction 的方法,把数据合并,Compaction 方法其实也是很多 NoSQL 架构中的一个重要优化过程。
Log_Structure 结构的优化
剩下的醒来再撸了。