什么是平衡二叉树(AVL)?
平衡二叉树是一棵合理的二叉排序树。
怎么保证合理?平衡二叉树左右子树高度差不超过1。
1. 如何构建一棵平衡二叉树?本质上跟构建二叉排序树一致。
2.在构建二叉排序树的过程中,如果发现树不符合特性,需要进行调整。 LL RR RL LR
如何判断调整类型:
1.找到失衡树的根结点root。
2.找到导致树失衡的结点node。
判断node在root的哪一侧。
3.判断node在root孩子的哪一侧。
四种调整方法:RR
LL:
LR:
RL:
1.建立平衡二叉树的过程,就是去建立一棵二叉排序树的过程。
2.在建立过程中,我们需要进行调整,所以我们需要在结构体当中,加一个字段来标识树的高度。
3.调整过程。
LR和RR的等效处理:
代码实现:
#include<stdio.h>
#include<stdlib.h>
typedef struct TreeNode
{
int data;
int height;
struct TreeNode* lchild;
struct TreeNode* rchild;
}TreeNode;
int getHeight(TreeNode* node)
{
return node ? node->height : 0;//三目运算符使用,可以借鉴
}
int max(int a, int b)
{
return a > b ? a : b;
}
void rrRotation(TreeNode* node, TreeNode** root)
{
TreeNode* temp = node->rchild;
node->rchild = temp->lchild;
temp->lchild = node;
node->height = max(getHeight(node->lchild), getHeight(node->rchild)) + 1;
temp->height = max(getHeight(temp->lchild), getHeight(temp->rchild)) + 1;
*root = temp;
}
void llRotation(TreeNode* node, TreeNode** root)
{
TreeNode* temp = node->lchild;
node->lchild = temp->rchild;
temp->rchild = node;
node->height = max(getHeight(node->lchild), getHeight(node->rchild)) + 1;
temp->height = max(getHeight(temp->lchild), getHeight(temp->rchild)) + 1;
*root = temp;
}
void avlInsert(TreeNode** T, int data)
{
if (*T == NULL)
{
*T = (TreeNode*)malloc(sizeof(TreeNode));
(*T)->data = data;
(*T)->height = 0;
(*T)->lchild = NULL;
(*T)->rchild = NULL;
}
else if (data < (*T)->data)
{
avlInsert(&((*T)->lchild), data);
//拿到当前节点左右子树的高度
int lHeight = getHeight((*T)->lchild);
int rHeight = getHeight((*T)->rchild);
//判断高度差
if (lHeight - rHeight == 2)
{
if (data < (*T)->lchild->data)
{
//RR调整
llRotation(*T, T);
}
else
{
//RL调整
rrRotation((*T)->lchild, &((*T)->lchild));
llRotation(*T, T);
}
}
}
else
{
avlInsert(&((*T)->rchild), data);
//拿到当前节点左右子树的高度
int lHeight = getHeight((*T)->lchild);
int rHeight = getHeight((*T)->rchild);
//判断高度差
if (rHeight - lHeight == 2)
{
if (data > (*T)->rchild->data)
{
//RR调整
rrRotation(*T, T);
}
else
{
//RL调整
llRotation((*T)->rchild, &((*T)->rchild));
rrRotation(*T, T);
}
}
}
(*T)->height = max(getHeight((*T)->lchild), getHeight((*T)->rchild)) + 1;
}
void noRecursion(TreeNode* T)
{
if (T == NULL)
{
return;
}
printf("%d ", T->data);
noRecursion(T->lchild);
noRecursion(T->rchild);
}
int main()
{
TreeNode* T = NULL;
int nums[] = { 1,8,6,7,10 };
for (int i = 0; i < 5; i++)
{
avlInsert(&T, nums[i]);
}
noRecursion(T);
system("pause");
return 0;
}
测试结果: