树在计算机中是一种非常重要的数据结构。
二叉树:对树的定义都是递归的,如果该树为一颗二叉树,那么所有子树也是一颗二叉树。
树的层数:根结点所在的层数为第一层。
叶子结点的个数=度为2的结点数+1
满二叉树:如果树有n层,那么树的总结点数为2的n次方-1。
完全二叉树:树的结点总是从上往下,从左往右排列。
堆:堆是一颗完全二叉树,且根结点大于所有的子结点(大根堆),所有的子树也是堆。堆可以用来进行排序。
二叉搜索树:根结点的值比左子树的所有结点都要大,比右子树的所有结点都要小,所有子树也是一颗二叉搜索树。二叉搜索树经常用于查找,查找效率为O(树的高度)。所以如果某个二叉树一直往左边切斜,效率将会降为O(n)(n为结点个数,即变成了线性链表)。
平衡二叉树(AVL):为了让结点均匀分布,降低树的高度,使得查找效率始终在O(logN)。会将树rebalance.
AVL tree is a self-balancing Binary Search Tree (BST) where the difference between heights of left and right subtrees cannot be more than one for all nodes.
红黑树:红黑树也是一颗自平衡的二叉搜索树,只不过它的每个结点都有颜色,这些颜色用来保证在插入和删除过程中树始终保持相对平衡。
When the tree is modified, the new tree is subsequently rearranged and repainted to restore the coloring properties. The properties are designed in such a way that this rearranging and recoloring can be performed efficiently.
In addition to the requirements imposed on a binary search tree, the following must be satisfied by a red–black tree:
- Each node is either red or black.
- The root is black.
- All leaves (NIL) are black.
- If a node is red, then both its children are black.
-
Every path from a given node to any of its descendant NIL nodes contains the same number of black nodes.
the path from the root to the farthest leaf is no more than twice as long as the path from the root to the nearest leaf.
B树:B树也是一颗用于搜索的树,搜索效率非常高(因为树的高度大大降低),且是平衡的,与平衡二叉树不同的是,B树每个结点可以存放多个值,每个父亲结点也可以有多个子树。
B树的来源:文件系统或数据库中有大量的记录,for example,1,000,000.这些数据都是存放在磁盘中的,每次读取一条记录,磁盘将会有寻道时间和旋转延迟,大约为10毫秒。
如果这一百万条记录已经排好序(主键索引),那么通过构建二叉搜索树,使用二分查找,将在O(logN)个比较级中找到想要查找的具体记录,也就是比较20次。每一次比较,都是先在磁盘上找到一条记录,与目标值比较,如果不相等,则继续折半,去查找另外一条记录。这样进行磁盘访问的次数将会在20次左右,总的时间为200毫秒,即0.2秒。
但是独立的记录被成组地记录在磁盘块上,一个磁盘块可能为16 千字节,如果每笔记录大小为160 字节,那么一个块可以存储100 笔记录。我们就可以通过创建辅助索引,使得该索引中包含每块磁盘块上的首笔记录。那么1,000,000/100=10,000,也就是说,现在只需要对这一万条记录进行折半查找,快速定位到具体的磁盘块,然后再在具体的磁盘块上进行详细的查找,这样就只需要比较8个比较级。
创建辅助索引的好处是可以重复地给辅助索引创建辅助索引(该索引存放的是每100个记录的首记录)。那样可以实现一个只拥有100 入口,能填满一整个磁盘块的辅助-辅助索引。该辅助-辅助索引现在只需要对100个数据进行折半查找。定位到具体的分块后,继续在辅助索引中定位,当定位到具体的磁盘块后,就可以在磁盘块上详细的找到了。这样实际上只需要进行三次磁盘访问,就可以找到到具体的记录。
辅助索引,使得查找问题从约为log2(N) 磁盘读取开销的二分查找,变成logb(N) 磁盘读取开销的查找,其中b为分块因素(每分块的入口数目:b = 100 。log100(1,000,000) = 3 次读取)。
在实际中,如果主数据库被频繁查找,辅助-辅助索引和大部分的辅助索引可能会存储在磁盘缓存中,所以它们不会产生磁盘读取。所以实际上前两次定位只需要在缓存中进行计算,真正的磁盘读取只有最后的一次。
那么需要如何维护索引呢?如果删除一条记录,索引可以保持不变,记录只需要标记为已删除。但是插入将是个灾难,因为需要给插入的记录制造空间。在文件中第一笔记录后插入记录需要把所有记录向后偏移一个位置,这样就会使索引发送大量变动。一种做法是预留一些空间给插入操作。磁盘块有一些空闲空间允许后来的插入,而不是高密度地填充。这些记录可以被标记为像是已删除的记录。
B树使用了以上所有的想法。
B+树:是B树的一个变种,但它比B Tree更适合实际应用中操作系统的文件索引和数据库索引,因为B+ Tree的每个节点不包括数据只有key,所以内存中可以容纳更多的key。
1)不可能在非叶子结点命中。非叶子结点相当于是叶子结点的索引,叶子结点相当于是存储数据的数据层。
2)所有关键字都出现在叶子结点的链表中。
B+树的根结点为辅助-辅助索引,第二层为辅助索引,第三层为磁盘块上的具体数据。这样树的高度将会变为3,大大提高了查询的效率。