- 为什么要在AVL树的基础上设计红黑树?
https://blog.csdn.net/mmshixing/article/details/51692892
红黑树的查询效率稍逊于AVL树,但插入和删除操作的复杂度会比较低。因为它不追求完全平衡,在插入和删除时需要Rebalance的次数会比较少,而且单次Rebalance的复杂度也比AVL要低。总的来说红黑树是牺牲严格的高度平衡来换取维护效率。
- 树的深度和高度
- 深度和高度都是从1开始计数,只有一个根节点的数的深度和高度都是1;
- 一部分书籍将深度和高度等同,还有一部分将深度从上向下计数,高度从下往上计数,这种定义下,深度第N层和高度第N层指的并不是同一层。
- AVL树操作复杂度分析
- end
二叉树
http://blog.jobbole.com/111680/
- 二叉树:
对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1。
- 满二叉树:第N层的叶子节点数为2的n-1次方
- 完全二叉树:前h-1层的树是满的,h层的节点靠左排列
- 平衡二叉树:任何一个结点的左树和右树的高度相差不超过1.
- 二叉搜索树:左节点的值小于根节点的值,右节点的值大于根节点的值
AVL树:平衡二叉搜索树
既是平衡二叉树又是二叉搜索树,由Adelse-Velskil和Landis提出,所以叫AVL树。通过在插入或者删除时进行一些维护达到平衡效果。
- 初始化时的操作:
- 插入的维护操作(LogN的下沉和旋转):分为LL(left-left)、RR(right-right)、LR、RL四种类型
- LL时使用右旋
- RR时使用左旋
- LR时先将R左旋成为LL结构,再右旋。
- RL时先将L右旋成为RR结构,再左旋。
- 删除时的维护操作(LogN):需要分情况:只有一个子树,有两个子树(子树的差是0,子树的差是1(删的是高树,删的是矮树))
红黑树:
节点不是黑色就是红色,且满足以下三个性质
- 根节点和外部节点都是黑色
- 根节点和外部节点中不能有连续的红色节点
- 根到外部节点都有数目相同的黑色节点
红黑树是二叉搜索树,不是严格的平衡二叉树,但它的定义可以保证从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。因为黑色节点的数目是相同的,所以节点多的路径多出来的是红色节点,红色节点又不能连续出现,所以红色节点只能穿插着黑色节点出现,这就导致了红色节点的数量最多和黑色节点的数量一致,所以从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。
插入时的操作
删除时的操作
B树(balance-tree):
- 多叉,不仅平衡而且每个叶子的高度一样。
- 每一个节点包括关键字、与关键字相联系的卫星数据(存储数据本身还是数据的指针并没有规定)、指向子节点的指针。
- 规定一个最小度数,则除了根节点外的每个节点的关键字个数在[t-1,2t-1]之间
也可以规定m阶B树,则除了根节点外的每个节点的关键字个数在[m/2-1,m-1]之间。
- 假设每一个节点对应一个磁盘块,多叉的特性,降低了树的深度,减少了磁盘IO次数。
B+树:在B树的基础上
- 所有的关键字都在叶子节点上,非叶子节点上的关键字都是其子树节点关键字的复制(所以上面节点和下面节点的关键字会有重复)。
- 在叶子节点增加指向下一个叶子节点的指针(便于对数据的顺序访问)。
优点:
- 节点不存储数据,内存固定的情况下就可以存储更多的关键字,树的层数就更小。
- 所有的数据都在同一层上,查询效率就更稳定。
B*树:
- 在非叶子和叶子节点都增加指针。这样在某个非叶子节点满了以后可以复制一部分数据到邻近节点(B+树是分裂成两个磁盘块)。
Trie树:字典树
最小堆:
是一个完全二叉树,每个节点都小于它的叶子节点。
- 堆的创建(由一个普通数组转化为符合最小堆概念的数组)
将数组看成树,从树的最下面一层开始,一层一层的逐渐冒泡。
- 插入时的维护(logN复杂度)
先将新数据插入尾部,然后将新数据向上冒泡。
- 删除时的维护(logN复杂度)
将最后一个节点填充到顶部,然后将新数据向下冒泡。
huffman树:
每个叶子节点都有权值,叶子权值*叶子深度的累加和最小的二叉树叫huffman树。
创建过程:以{7,5,2,4}为例子
取最小的两个值2,4合成一个三元组
{7,5,2,4}变为{7,5,6},取最小值5,6构成三元组
{7,5,6}变为{7,11},取7,11构成三元组
因为只有叶子节点是有效节点,每个叶子节点路径编码又不可能是其他叶子节点路径编码的前缀,所以haffman树适合于进行编码。