平衡二叉树(AVL树)
2013-06-23 21:53
351 查看
平衡二叉树的相关概念概念:
平衡二叉树是一种二叉排序树,它具有如下性质:1、每一个结点的左子树和右子树的深度最多相差1;
2、每一个结点的左子树和右子树也都是平衡二叉树
平衡因子(BF,balance factor):
结点的平衡因子是该结点的左子树的深度与右子树的深度之差,有-1,0,1三种值。
最小不平衡子树
距离插入结点最近,且平衡因子的绝对值大于1的结点为根的子树,我们称为最小不平衡子树。
平衡二叉树构建的基本思想:
在构建二叉排序树的过程中,每当插入一个结点时,首先检查是否因插入而破坏了树的平衡性。若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。对平衡树进行调整归纳的4种情况:
(1)LL型在A的左孩子的左子树上插入结点F,使A的平衡因子由1变为2,则进行一次顺时针旋转调整。由于结点A和D发生冲突,将D变为A的左子树,如图:
(2)RR型
和LL型刚刚相反,如图:
(3)LR型
在A的左孩子的右子树上插入结点F,使A的平衡因子由1变为2,则先进行一次逆时针旋转,再进行一次顺时针旋转。即先使之成为LL型,再按照LL型处理。如图:
(4)RL型
和LR型刚刚相反,如图:
算法代码:
处理左平衡代码#define LH 1 #define EH 0 #define RH -1 typedef struct BiNode { int data; int bf; struct BiNode *lchild,*rchild; }BiNode; void LL(BiNode * p) { BiNode * L; L = p->lchild; p->lchild = L->rchild; L->rchild = p; p = L; } void RR(BiNode * p) { BiNode * R; R = p->rchild; p->rchild = R->lchild; R->lchild = p; p = R; } void LeftBalance(BiNode * p)//处理左边平衡情况 { BiNode * L,* Lr; L = p->lchild; switch(L->bf) { case LH://新结点插入在p的左孩子的左子树上,要作顺时针旋转,即LL处理 p->bf = L->bf = EH; LL(p); break; case RH://新结点插入在p的左孩子的右子树上,作LR处理 Lr = L->rchild; switch(Lr->bf)//修改p及其左孩子的bf { case LH: p->bf = RH; L->bf = EH; break; case EH: p->bf = L->bf = EH; break; case RH: p->bf = EH; L->bf = LH; break; } Lr->bf = EH; RR(p->lchild);//逆时针处理 LL(p);//顺时针处理 } }右平衡与左平衡处理情况相反,代码稍加修改就OK了,这里就不给出了,可以参考以上代码。
再看看平衡二叉树整个处理过程(代码):
//在平衡二叉树T中若不存在和e相同的结点,则插入一个数据元素为e的新结点并返回1,否则返回0。若 //因二叉排序树失去平衡,则作旋转处理,taller反映T长高与否 int InsertAVL(BiNode * T,int e,bool * taller) { if (!T) { T = (BiNode *)malloc(sizeof(BiNode)); T->data = e; T->lchild = T->rchild = NULL; T->bf = EH; * taller = TRUE; } else { if (e == T->data)//若存在相同元素 { *taller = FALSE; return FALSE; } if (e < T->data)//在T的左子树搜索 { if (!InsertAVL(T->lchild,e,taller))//递归处理 return FALSE; if (*taller)//已插入到T的左子树中且左子树“长高” { switch(T->bf)//检查T的平衡度 { case LH://原本左子树比右子树高,需作左平衡处理 LeftBalance(T); *taller = FALSE; break; case EH://原本左右子树等高,现因左子树增高而树增高 T->bf = LH; *taller = TRUE; break; case RH://原本右子树比左子树高,现左右子树等高 T->bf = EH; *taller = FALSE; break; } } } else//在T的右子树搜索 { if (!InsertAVL(T->rchild,e,taller)) return FALSE; if (*taller) { switch(T->bf) { case LH: T->bf = EH; *taller = FALSE; break; case EH: T->bf = RH; *taller = TRUE; break; case RH: RightBalance(T); *taller = FALSE; break; } } } } return TRUE; }
相关文章推荐
- PHP实现平衡二叉树(AVL树)
- 一步一步写平衡二叉树(AVL树)
- 请要相信我,30分钟让你掌握AVL树(平衡二叉树)
- 平衡二叉树——AVL树的实现
- 平衡二叉树(AVL树)
- 平衡二叉树-AVL树的构建和操作
- 平衡二叉树(AVL树)
- 平衡二叉树(AVL树)算法 Java实现
- 平衡二叉树(AVL树)
- 平衡二叉树(AVL树)一图一步骤代码实现左旋右旋,左右平衡操作
- 平衡二叉树 AVL树
- 平衡二叉树(AVL树)
- 看数据结构写代码(56) 平衡二叉树(AVL树)
- JAVA实践自平衡二叉树(AVL树)
- 高度平衡二叉树——AVL树
- 平衡二叉树,AVL树之图解篇
- 剑指offer--平衡二叉树--AVL树
- 平衡二叉树之AVL树的旋转
- 动态查找---->平衡二叉树(AVL树)
- 【数据结构】平衡二叉树[AVL树](一)——插入