总述
有序表拥有哈希表的所有操作。并且Key有序
有序表所有操作都是log(N)级别的,可以由红黑树、avl、SB(size balance tree)、跳表skiplist这些实现出来,没有谁最好,差的只是常数项。前三个是平衡搜索二叉树系列,但是不是严格的平衡树,差不多就行
不同类型的平衡树改成平衡型的操作是一样的,就是左旋和右旋,不同的是判断平衡性的条件。
不论哪种平衡性都可以不用手撕他的,只要搞清楚原理就行
平衡性的树
狭义的:任何子树的高度差不超过1
广义的:任何子树的数量或者高度差不多
左旋和右旋
左旋和右旋指的是头结点向左边还是向右边旋转的方向
左旋
右旋
如何调整成平衡性的树
- 先从底下向上查起,看各个节点的平衡性
- 如果平衡性不同,就加以左旋或右旋进行改变
- 如果进行了删除操作,就将删除节点的右子树中没有左节点的最小的取出来代替它,同时在取出来的最小节点的上一层开始查平衡性
介绍AVL树及其实现
平衡性
维持平衡性的标准:严格保证左树和右树的差不超过1
实现
- 当插入或者删除一个结点时,可能会让整棵树AVL不平衡。此时,只需要把最小不平衡子树调整即可恢复整体的平衡性。
- 四种类型
- LL型 需要两次右旋
- RR型 需要两次左旋
- LR型 需要先左旋然后再右旋
- RL型 需要先右旋然后再左旋
介绍SB树及其实现
平衡性
维持平衡性的标准:(大小指结点数)
- 每个子树的大小,不小于其兄弟的子树的大小
- 既每棵叔叔树的大小,不小于其任何侄子树的大小
实现
LL型
LL型:对于一个结点来说,它的左孩子的左孩子大小大于它的叔叔
LL型的实现
步骤:
- 右旋
- 子节点变化的节点重新m(x),上图中就是m(A),m(B)
LR型
LR型:对于一个结点来说,它的左孩子的右孩子大小大于它的叔叔
LR型的实现
////////////////////////////////////////////////////////////////////////////////////
步骤:
- 先左旋
- 再右旋
- 子节点变化的节点重新m(x),上图中就是m(A),m(E),m(B)
谈一谈红黑树
注意:这个不常用
平衡性条件:
- 一个点要么是红要么是黑
- 整棵树的头结点一定是黑,叶节点一定是黑(这里的叶节点和平常我们讲的不同,这里指的是null节点)
- 红点不相邻
- 如果cur为当前头节点,则每条从cur到结束的路黑色的节点一样多,因为红黑红黑这样排列最长,全黑路最短,此条保证了路最长与最短之间不超过两倍长度的关系
介绍SkipList及其实现
平衡性
利用随机函数打破输入规律