1.平衡二叉树的定义
平衡二叉树,简称平衡树(AVL树)—-树上任一结点的左子树和右子树的高度之差不超过1. 结点的平衡因子=左子树高-右子树高,值只可能是-1,0,1. 类型定义
typedef struct AVLNode{
int key;
int balance;
struct AVLNode *lchild, *rchild;
}AVLNode, *AVLTree;
2.平衡二叉树的插入
插入结点时,首先按照二叉排序树处理,若插入结点后破坏了平衡二叉树的特性,需对平衡二叉树进行调整。
3.平衡二叉树的调整
调整方法:找到离插入结点最近且平衡因此绝对值超过1的祖先结点,以该结点为根的子树称为最小不平衡子树,可讲重新平衡的范围局限于这颗子树。 调整最小不平衡子树: LL:在A的左孩子的左子树中插入导致不平衡 RR:在A的右孩子的右子树中插入导致不平衡 LR:在A的左孩子的右子树中插入导致不平衡 RL:在A的右孩子的左子树中插入导致不平衡 1)LL平衡旋转(右单旋转)。由于在结点A的左孩子(L)的左子树(L)上插入了新结点,A的平衡因子由1增至2,导致以A为根的子树失去平衡,需要一次向右上旋转代替A成为根结点,将A结点向右下旋转成为B的右子树的根结点,而B的原右子树则作为A结点的左子树。 2)RR平衡旋转(左单旋转)。由于在结点A的右孩子(R)的右子树(R)上插入了新结点,A的平衡因此由-1减至-2,导致以A为根的子树失去平衡,需要一次向左的旋转操作。将A的右孩子B向上旋转代替A成为根结点,将A结点向左下旋转成为B的左子树的根结点,而B的原左子树则作为A结点的右子树。 3)LR平衡旋转(先左后右双旋转)。由于A的左孩子(L)的右子树(R)上插入新结点,A的平衡因此由1增至2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先左旋转后右旋转。先将A结点的左孩子B的右子树的根结点C向左上旋转提升到B结点的位置,然后再把C结点向右上旋转提升到A结点的位置。 4)RL平衡旋转(先右后左双旋转)。由于在A的右孩子(R)的左子树(L)上插入新结点,A的平衡因子由-1减至-2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先右旋转后左旋转。先将A结点的右孩子B的左子树的根结点C向右上旋转提升到B结点的位置,然后再把C结点向左上旋转提升到A结点的位置。 总结: A.只有左孩子才能右上旋: 实现f向右下旋转,p向右上旋转: 其中f是爹,p为左孩子,gf为他爹 a.f->lchild=p->rchild; b.p->rchild=f; c.gf->lchild/rchild=p;
B.实现f向左下旋转,p向左上旋转: 其中f是爹,p为右孩子,gf为他爹 a.f->rchild=p->lchild; b.p->lchild=f; c.gf->lchild/rchild=p;
LL:在A的左孩子的左子树中插入导致不平衡,调整:A的左孩子结点右上旋 RR:在A的右孩子的右子树中插入导致不平衡,调整:A的右孩子结点左上旋 LR:在A的左孩子的右子树中插入导致不平衡,调整:A的左孩子的右孩子先左上旋再右上旋 RL:在A的右孩子的左子树中插入导致不平衡,调整:A的右孩子的左孩子,先右上旋后左上旋
4.查找效率分析
若树高为h,则最坏情况下,查找一个关键字最多需要对比h次,即查找操作的时间复杂度不可能超过O(h)
|