Mit6.006-lecture07-BinaryTrees2AVL

一、上次与今日目标

序列数据结构 操作,最坏情形O
容器(container) 静态(static) 动态(dynamic)
build(x) get_at(i)
set_at(i, x)
insert_first(x)
delete_first()
insert_last(x)
delete_last()
insert_at(i, x)
delete_at(i)
二叉树 n h h h h
AVL树 n logn logn logn logn
集合数据结构 操作,最坏情形O
容器(container) 静态(static) 动态(dynamic) 顺序(order)
build(X) find(k) insert(x)
delete(k)
find_min()
find_max()
find_prev(k)
find_next(k)
二叉树 nlogn h h h h
AVL树 nlogn logn logn logn logn

二、高度平衡

  • 如何维持高度 h = O ( log ⁡ n ) h=\mathcal{O}(\log n) h=O(logn),n为树中节点的数量

  • 在动态操作中维持树的高度为 O ( log ⁡ n ) \mathcal{O}(\log n) O(logn)的二叉树称为平衡的

    • 有多种平衡方式(红黑树、伸展树SplayTree、2-3Tree)

    • 首次提出的平衡方式为AVL树

三、旋转(Rotations)

  • 需要降低树的高度,而不改变遍历顺序,因此我们表示相同序列的项目

  • 保留遍历顺序时,如何改变树的结构?旋转!

D
B
E
A
C
B
A
D
C
E

图1 rotate_right() 得到图2、图2 rotate_left() 得到图2

  • 旋转重新链接 O ( 1 ) \mathcal{O}(1) O(1)指针更改树结构、维持遍历顺序

四、Rotations Suffice

  • 声明: O ( n ) \mathcal{O}(n) O(n)次旋转可以转换二叉树为任意其他二叉树(拥有相同遍历顺序)

  • 证明:按遍历顺序重复执行最后可能的右旋;结果树为经典的链表。每次旋转最后节点的深度增加1。最终链中最后节点的深度为 n − 1 n-1 n1,因此最多执行n-1次旋转。反向旋转得到目标树

  • 通过使用 O ( n ) \mathcal{O}(n) O(n)次旋转,可以维持高度平衡来完全平衡二叉树,但很慢

  • 每次操作,我们将耗时 O ( log ⁡ n ) \mathcal{O}(\log n) O(logn)维持树的平衡

五、AVL树:高度平衡

  • AVL树维持高度平衡(也称作AVL属性)

    • 如果左、右子树高度最多相差1,那么节点是高度平衡的

    • 让节点的偏斜为右子树高度减左子树高度

    • 如果它的偏斜为-1、0、1,那么节点是高度平衡的


  • 声明:拥有高度平衡节点的二叉树,高度为 h = O ( log ⁡ n ) ,比如 n = 2 Ω ( h ) h=\mathcal{O}(\log n),比如n=2^{\Omega(h)} h=O(logn),比如n=2Ω(h)

  • 证明:任意高度为h的树,最少节点 F ( h ) = 2 Ω ( h ) F(h)=2^{\Omega(h)} F(h)=2Ω(h)

    F(0)=1,F(1)=2,F(h)=1+F(h-1)+F(h-2) >= 2F(h-2) => F ( h ) ≥ 2 h / 2 F(h)\ge2^{h/2} F(h)2h/2


你可能感兴趣的:(算法,算法)