代码内容来自《大话数据结构》,程杰著。
原书中没有RightBalance函数实现,本处按照LeftBalance实现。
#include <stdio.h>
#include <stdlib.h>
#define LH +1 //左高
#define EH 0 //相等
#define RH -1 //右高
typedef struct BitNode {
int data;//结点数据
int bf;//结点平衡因子
struct BitNode * lchild, *rchild;
}BitNode, *pBitNode;
typedef enum {FALSE, TRUE} Status;
//右旋转
void R_Rotate(pBitNode * p) {
pBitNode L;
L = (*p)->lchild;
(*p)->lchild = L->rchild;
L->rchild = (*p);
*p = L;
}
//左旋转
void L_Rotate(pBitNode * p) {
pBitNode R;
R = (*p)->rchild;
(*p)->rchild = R->lchild;
R->lchild = (*p);
*p = R;
}
//左平衡调节
void LeftBalance(pBitNode *T) {
pBitNode L, Lr;
L = (*T)->lchild;
switch (L->bf)
{
//情况2
case LH: {
(*T)->bf = L->bf = EH;
R_Rotate(T);
}
break;
//情况1
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);
}
break;
}
}
void RightBalance(pBitNode *T) {
pBitNode R, Rl;
R = (*T)->rchild;
switch (R->bf)
{
case RH: {
(*T)->bf = R->bf = EH;
L_Rotate(T);
}
break;
case LH: {
Rl = R->lchild;
switch (Rl->bf)
{
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);
L_Rotate(T);
}
break;
}
}
Status InsertAVL(pBitNode *T, int e, Status *taller) {
//空节点
if (!*T) {
*T = (pBitNode)malloc(sizeof(BitNode));
(*T)->data = e;
(*T)->lchild = (*T)->rchild = NULL;
(*T)->bf = EH;
*taller = TRUE;
return TRUE;
}
//已经存在和e有相同关键字结点
if (e == (*T)->data) {
*taller = FALSE;
return FALSE;
}
//插入结点
if (e < (*T)->data) {
if (!InsertAVL(&(*T)->lchild, e, taller)) {
return FALSE;
}
if (*taller) {
switch ((*T)->bf) {
case LH:
LeftBalance(T);
*taller = FALSE;
break;
case EH:
(*T)->bf = LH;
*taller= TRUE;
break;
case RH:
(*T)->bf = EH;
*taller = FALSE;
break;
}
}
}
else {
if (!InsertAVL(&(*T)->rchild, e, taller)) {
return FALSE;
}
if (*taller) {
switch ((*T)->bf) {
case RH:
RightBalance(T);
*taller = FALSE;
break;
case EH:
(*T)->bf = RH;
*taller= TRUE;
break;
case LH:
(*T)->bf = EH;
*taller = FALSE;
break;
}
}
}
return TRUE;
}
//先根遍历
void PreOrderTraverse(pBitNode T) {
if (T == NULL) {
return;
}
printf("%d",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
//中根遍历
void MidOrderTraverse(pBitNode T) {
if (T == NULL) {
return;
}
MidOrderTraverse(T->lchild);
printf("%d",T->data);
MidOrderTraverse(T->rchild);
}
//后根遍历
void LastOrderTraverse(pBitNode T) {
if (T == NULL) {
return;
}
LastOrderTraverse(T->lchild);
LastOrderTraverse(T->rchild);
printf("%d",T->data);
}
void main() {
int i;
int a[10] = {3,2,1,4,5,6,7,10,9,8};
Status taller;
pBitNode T=NULL;
for (i=0; i<10; i++) {
InsertAVL(&T, a[i], &taller);
PreOrderTraverse(T);
printf(" ");
MidOrderTraverse(T);
printf(" ");
LastOrderTraverse(T);
printf("\n");
}
}
LeftBalance用于处理以下两种情况:
情况1: 情况2:
调整后结果:
情况1之所以在代码中存在两次旋转,是因为情况1需要首选左旋为情况2,后再右旋才能达到最后的调整结果。
RightBalance正好处理与LeftBalance相反情况。