平衡二叉树是一种二叉排序树,其中每一个结点左子树和右子树高度差至多等于1。
二叉树左子树深度减去右子树深度的值称为平衡因子。
平衡因子只可能-1、0、1。
距离插入结点最近的,且平衡因子的绝对值大于1的结点的根的子树我们称为最小不平衡子树。
//二叉树的二叉链表结点结构定义
typedef struct BiTNode
{
int data;
int bf;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//对以p为根的二叉排序树作右旋处理
//处理之后p指向新的树根结点,即旋转处理之前的左子树的根结点
void R_Rotate(BiTree *p)
{
BiTree L;
L = (*p)->lchild;
(*p)->lchild = L->rchild;
L->rchild = (*p);
*p = L;
}
//对以p为根的二叉排序树作左旋处理
//处理之后p指向新的树根结点,即旋转处理之前的右子树的根结点0
void L_Rotate(BiTree *p)
{
BiTree R;
R = (*p)->rchild;
(*p)->rchild = (*p)->lchild;
R->lchild = (*p);
*p = R;
}
#define LH +1 //左高
#define EH 0 //等高
#define RH -1 //右高
//对以指针T所指结点为根的二叉树作作平衡旋转处理
//本算法结束时,指针T指向新的根结点
void LeftBalance(BiTree *T)
{
BiTree L,Lr;
L = (*T)->lchild;
switch(L->bf)
{
//检查T的左子树的平衡度,并作相应平衡处理
case LH: //新结点插入在T的左孩子的左子树上,要作单右旋处理
(*T)->bf = L->bf = EH;
R_Rotate(T);
break;
case RH: //新结点插入在T的左孩子的右子树上,要作双旋处理
Lr = L->rchild; //Lr指向T的左孩子的右子树根
switch(Lr->bf) //修改T及其左孩子的平衡因子
{
case LH:
(*T->bf = RH)
L->bf = EH;
break;
case EH:
(*T)->bf = L->bf = EH;
break;
case RH:
(*T)->bf = EH;
L->bf = LH;
break;
}
Lr->bf = EH;
L_Rotate(&(*T)->lchild); //对T的左子树作左旋平衡处理
R_Rotate(T); //对T作右旋平衡处理
}
}
//若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个
//数据元素为e的新结点并返回1,否则返回0,若因插入而使二叉排序树
//失去平衡,则作平衡旋转处理布尔变量taller反映T长高与否。
Status InsertAVL(BiTree *T,int e,Status *taller)
{
if(!*T)
{
//插入新结点,树长高,置taller为TRUE
*T = (BiTree)malloc(sizeof(BiTNode));
(*T)->data = e;
(*T)->lchild = (*T)->rchild = NULL;
(*T)->bf = EH;
*taller = TRUE;
}
else
{
if(e == (*T)->data)
{
//树中已存在和e有相同关键字的结点则不再插入
*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) //已插入到T的右子树且右子树长高
{
switch ((*T)->bf) //检查T的平衡度
{
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;
}
}
多路查找树,其每一个结点的孩子数可以多于两个,且每一个结点处可以存储多个元素。
2-3树是一棵多路查找树:其中的每一个结点都具有两个孩子或三个孩子。
一个2结点包含一个元素和两个孩子(或没有孩子)。
一个3结点包含一大一小两个元素和三个孩子(或没有孩子)。
B树是一种平衡的多路查找树。
结点最大的孩子数目称为B树的阶。