平衡二叉树的建立,在二叉树搜索中具有重要意义,所以今天来记录一下AVL树的建立。
#include <bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100
typedef struct BiTNode
{
int data;//节点数据
int bf;//平衡因子
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
void R_Rotate(BiTree *P)//右旋操作
{
BiTree L;
L = (*P)->lchild;
(*P)->lchild = L->rchild;
L->rchild = *P;
*P = L;
}
void L_Rotate(BiTree *P)//左旋操作
{
BiTree R;
R = (*P)->rchild;
(*P)->rchild = R->lchild;
R->lchild = *P;
*P = R;
}
#define LH +1
#define EH 0
#define RH -1
void LeftBalance(BiTree *T)//左平衡旋转操作
{
BiTree L, Lr;
L = (*T)->lchild;
switch (L->bf)
{
case LH:
(*T)->bf = L->bf = EH;
R_Rotate(T);
break;
case RH:
Lr = L->rchild;
switch (Lr->bf)
{
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);
R_Rotate(T);
}
}
void RightBalance(BiTree *T)
{
BiTree R, Rl;
R = (*T)->rchild; /* R指向T的右子树根结点 */
switch (R->bf)
{ /* 检查T的右子树的平衡度,并作相应平衡处理 */
case RH: /* 新结点插入在T的右孩子的右子树上,要作单左旋处理 */
(*T)->bf = R->bf = EH;
L_Rotate(T);
break;
case LH: /* 新结点插入在T的右孩子的左子树上,要作双旋处理 */
Rl = R->lchild; /* Rl指向T的右孩子的左子树根 */
switch (Rl->bf)
{ /* 修改T及其右孩子的平衡因子 */
case RH: (*T)->bf = LH;
R->bf = EH;
break;
case EH: (*T)->bf = R->bf = EH;
break;
case LH: (*T)->bf = EH;
R->bf = RH;
break;
}
Rl->bf = EH;
R_Rotate(&(*T)->rchild); /* 对T的右子树作右旋平衡处理 */
L_Rotate(T); /* 对T作左旋平衡处理 */
}
}
bool InsertAVL(BiTree *T, int e, bool *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;
}
int main(void)
{
int i;
int a[10] = { 3,2,1,4,5,6,7,10,9,8 };
BiTree T = NULL;
bool taller;
for (i = 0; i<10; i++)
{
InsertAVL(&T, a[i], &taller);
}
printf("本样例建议断点跟踪查看平衡二叉树结构\n");
return 0;
}