二叉搜索树与AVL树

目录

二叉搜索树

AVL树

AVL树的旋转

LL旋转

LR旋转

RR旋转

 RL旋转


二叉搜索树

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
左小右大:小于根节点的数放左边,大于根节点的数放右边。
重复的节点值不允许出现
二叉搜索树与AVL树_第1张图片
二叉搜索树中序遍历得到的值序列是递增有序的
如上图,中序遍历得到的序列为:[2, 5,9, 12, 14, 16, 17, 18, 19]
二叉搜索树是一种用于查找操作的高效数据结构。

因为在最坏的情况下,只需要查找一个分支上的数据,而不用检索每一个数据。查找的复杂度为O(lg n),n为树中的节点数。这里树必须保持平衡。保持平衡就是指对于给定数量的节点,要使得树的高度尽可能短。
保持二叉树处于平衡状态非常重要,因为这代表的我们查找的分支不会特别长。
如果一棵二叉树越来越不平衡,所有节点连成一条线。查找一个节点的复杂度就成了O(n),这相当于从头到尾查找。所以要采取一些办法来保持平衡

其中最好的办法就是将二叉树实现为AVL树(实际上红黑树的统计性能比AVL树更好,红黑树也是一种平衡搜素树)。

AVL树

AVL树是最早被发明的自平衡二叉查找树。在AVL树中,任一节点对应的两棵子树的最大高度差为1,因此它也被称为高度平衡树。,它的每一个节点都保存一份额外的信息:节点的平衡因子。节点的平衡因子是它的左子树的高度减去它的右子树的高度(有时相反)。带有平衡因子1、0或 -1的节点被认为是平衡的。带有平衡因子 -2或2的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。当插入节点时,AVL树需要自我调整,使得所有节点的平衡因子保持为+1,-1和0。

  • 平衡因子为+1:左倾斜
  • 平衡因子为-1:右倾斜
  • 平衡因子为0:平衡

查找、插入和删除在平均和最坏情况下的时间复杂度都是{\displaystyle O(\log {n})}

算法 平均 最差
空间 O(n) O(n)
搜索 O(log n) O(log n)
插入 O(log n) O(log n)
删除 O(log n) O(log n)

AVL树的旋转

AVL树的查找和插入节点操作和普通二叉树一样,但是,当向AVL树中 插入一个节点,还有一些额外工作要做:

  • 必须计算因为执行了 插入操作对平衡因子带来的改变
  • 如果任何平衡因子变成了±2,就必须从这个节点开始往下重新平衡这棵树

重新平衡的过程就称为旋转。

旋转操作用来重新平衡AVL树的某个部分,通过重新安排节点,同时又必须保持节点之间的关系:左节点小于父节点,右节点大于父节点。也就是必须保持该树仍是二叉树。旋转过后,旋转子树中的所有节点的平衡因子都为+1,-1或0。

共有四种旋转类型需要执行:LL、LR、RR和RL旋转。

设x代表刚插入的AVL树中的节点,设A为离x最近且平衡因子更改为±2的祖先。

LL旋转

当x位于A的左子树的左子树上时,执行LL旋转:

二叉搜索树与AVL树_第2张图片

设left为A的左子树,要执行LL旋转:

  1. 将A的左指针指向left的右子节点
  2. left的右指针指向A
  3. 将原来指向A的指针指向left

旋转过后,将A和left的平衡因子都改为0,所有其他的平衡因子没有改变。

LR旋转

当x位于A的左子树的右子树上时,执行LR旋转:

设left是A的左子节点,并设A的子孙节点grandchild为left的右子节点。

二叉搜索树与AVL树_第3张图片

RR旋转

当x位于A的右子树的右子树上时,执行RR旋转,RR旋转和LL旋转是对称关系。

二叉搜索树与AVL树_第4张图片

 RL旋转

当x位于A的右子树的左子树上时,执行RL旋转,RL旋转和LR旋转是对称的关系。

你可能感兴趣的:(数据结构与算法,二叉树,数据结构)