有序表

226 阅读3分钟

总述

有序表拥有哈希表的所有操作。并且Key有序

有序表所有操作都是log(N)级别的,可以由红黑树、avl、SB(size balance tree)、跳表skiplist这些实现出来,没有谁最好,差的只是常数项。前三个是平衡搜索二叉树系列,但是不是严格的平衡树,差不多就行

不同类型的平衡树改成平衡型的操作是一样的,就是左旋和右旋,不同的是判断平衡性的条件

不论哪种平衡性都可以不用手撕他的,只要搞清楚原理就行

平衡性的树

狭义的:任何子树的高度差不超过1

广义的:任何子树的数量或者高度差不多

左旋和右旋

左旋和右旋指的是头结点向左边还是向右边旋转的方向

左旋

image.png

右旋

image.png

如何调整成平衡性的树

  1. 先从底下向上查起,看各个节点的平衡性
  2. 如果平衡性不同,就加以左旋或右旋进行改变
  3. 如果进行了删除操作,就将删除节点的右子树中没有左节点的最小的取出来代替它,同时在取出来的最小节点的上一层开始查平衡性

介绍AVL树及其实现

平衡性

维持平衡性的标准:严格保证左树和右树的差不超过1

实现

  1. 当插入或者删除一个结点时,可能会让整棵树AVL不平衡。此时,只需要把最小不平衡子树调整即可恢复整体的平衡性。
  2. 四种类型
    1. LL型 需要两次右旋
    2. RR型 需要两次左旋
    3. LR型 需要先左旋然后再右旋
    4. RL型 需要先右旋然后再左旋 image.png

介绍SB树及其实现

平衡性

维持平衡性的标准:(大小指结点数)

  1. 每个子树的大小,不小于其兄弟的子树的大小
  2. 既每棵叔叔树的大小,不小于其任何侄子树的大小 image.png

实现

LL型

LL型:对于一个结点来说,它的左孩子的左孩子大小大于它的叔叔

image.png

LL型的实现

image.png

步骤:

  1. 右旋
  2. 子节点变化的节点重新m(x),上图中就是m(A),m(B)
LR型

LR型:对于一个结点来说,它的左孩子的右孩子大小大于它的叔叔

image.png

LR型的实现

image.png

////////////////////////////////////////////////////////////////////////////////////

image.png

步骤:

  1. 先左旋
  2. 再右旋
  3. 子节点变化的节点重新m(x),上图中就是m(A),m(E),m(B)

谈一谈红黑树

注意:这个不常用

平衡性条件:

  1. 一个点要么是红要么是黑
  2. 整棵树的头结点一定是黑,叶节点一定是黑(这里的叶节点和平常我们讲的不同,这里指的是null节点)
  3. 红点不相邻
  4. 如果cur为当前头节点,则每条从cur到结束的路黑色的节点一样多,因为红黑红黑这样排列最长,全黑路最短,此条保证了路最长与最短之间不超过两倍长度的关系

介绍SkipList及其实现

平衡性

利用随机函数打破输入规律

实现

跳表的讲解