平衡二叉树
- 平衡二叉树是一种二叉排序树,其中每个结点的左子树和右子树的高度差最大等于1。
- 距离插入结点最近的,且平衡因子(Banlance Factor)大于1的结点为根的子树,我们称为最小不平衡子树。
基本思想
在构建二叉排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的连接关系,进行相应选转,使之成为新的平衡子树。
代码实现
/*
* @Author: Xyh4ng
* @Date: 2022-11-27 18:59:27
* @LastEditors: Xyh4ng
* @LastEditTime: 2022-11-27 20:56:50
* @Description:
* Copyright (c) 2022 by Xyh4ng 503177404@qq.com, All Rights Reserved.
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct AVLNode
{
int data;
int bf;
struct AVLNode *lchild, *rchild;
} AVLNode, *AVLTree;
void LeftRotation(AVLTree *T)
{
AVLTree R;
R = (*T)->rchild;
(*T)->rchild = R->lchild;
R->lchild = *T;
*T = R;
}
void RightRotation(AVLTree *T)
{
AVLTree L;
L = (*T)->lchild;
(*T)->lchild = L->rchild;
L->rchild = *T;
*T = L;
}
void LeftBanlance(AVLTree *T)
{
AVLTree L, Lr;
L = (*T)->lchild;
switch (L->bf)
{
case 1: // LH
RightRotation(T);
(*T)->bf = L->bf = 0;
break;
case -1: // RH
Lr = L->rchild;
switch (Lr->bf)
{
case 1:
(*T)->bf = -1;
L->bf = 0;
break;
case 0:
(*T)->bf = 0;
L->bf = 0;
break;
case -1:
(*T)->bf = 0;
L->bf = 1;
break;
default:
break;
}
Lr->bf = 0;
LeftRotation(&(*T)->lchild);
RightRotation(T);
default:
break;
}
}
void RightBanlance(AVLTree *T)
{
AVLTree R, Rl;
R = (*T)->rchild;
switch (R->bf)
{
case -1: // RH
LeftRotation(T);
(*T)->bf = R->bf = 0;
break;
case 1: // LH
Rl = R->lchild;
switch (Rl->bf)
{
case -1:
(*T)->bf = -1;
R->bf = 0;
break;
case 0:
(*T)->bf = 0;
R->bf = 0;
break;
case 1:
(*T)->bf = 0;
R->bf = 1;
break;
default:
break;
}
Rl->bf = 0;
RightRotation(&(*T)->lchild);
LeftRotation(T);
default:
break;
}
}
void InsertAVLTree(AVLTree *T, int key, int *taller)
{
if (!*T)
{
*T = (AVLTree)malloc(sizeof(AVLNode));
(*T)->data = key;
(*T)->lchild = (*T)->rchild = NULL;
(*T)->bf = 0;
*taller = 1;
}
else
{
if (key == (*T)->data)
{
*taller = 0;
return;
}
else if (key < (*T)->data)
{
InsertAVLTree(&(*T)->lchild, key, taller);
if (*taller == 1)
{
switch ((*T)->bf)
{
case 1: // LH
LeftBanlance(T);
*taller = 0;
break;
case 0: // EH
(*T)->bf = 1;
*taller = 1;
break;
case -1: // RH
(*T)->bf = 0;
*taller = 0;
break;
default:
break;
}
}
}
else
{
InsertAVLTree(&(*T)->rchild, key, taller);
if (*taller == 1)
{
switch ((*T)->bf)
{
case 1: // LH
(*T)->bf = 0;
*taller = 0;
break;
case 0: // EH
(*T)->bf = -1;
*taller = 1;
break;
case -1: // RH
RightBanlance(T);
*taller = 0;
break;
default:
break;
}
}
}
}
}
void MidTraversal(AVLTree T)
{
if (!T)
{
return;
}
else
{
MidTraversal(T->lchild);
printf("%d, ", T->data);
MidTraversal(T->rchild);
}
}
int main()
{
int a[10] = {3, 2, 1, 4, 5, 6, 7, 10, 9, 8};
AVLTree T = NULL;
int taller = 0;
for (int i = 0; i < 10; i++)
{
InsertAVLTree(&T, a[i], &taller);
}
MidTraversal(T);
return 0;
}