平衡二叉树(AVLTree)是指带平衡条件的二叉查找树。AVLTree要求每个节点的左子树和右子树的高度之差最多为1。当因为插入或删除操作导致AVLTree不满足该平衡条件时就需要进行调整操作,包括单旋转和双旋转操作。也正是因为需要时刻保持树的平衡条件,从而使得AVLTree的插入和删除操作较为复杂。
以下给出AVLTree的递归实现。
AVLTree.h:
#ifndef _AVLTree_H
#define _AVLTree_H
struct AvlNode;
typedef struct AvlNode* Position;
typedef struct AvlNode* AvlTree;
typedef int ElementType;
AvlTree MakeEmpty(AvlTree& T);
Position Find(ElementType X,AvlTree T );
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X,AvlTree& T);
AvlTree Delete(ElementType X,AvlTree T);
int GetHeight(Position P);//获取节点的高度
//前序遍历AVLTree
void PPrintTree(AvlTree T);
//中序遍历AVLTree
void MPrintTree(AvlTree T);
//后序遍历AVLTree
void LPrintTree(AvlTree T);
//辅助函数
//单旋转 返回新根节点(按失衡原因分为四种旋转)
Position SingleRotateWithLeft(Position K2);//左左
Position SingleRotateWithRight(Position K2);//右右
//双旋转 返回新的根节点
Position DoubleRotateWithLeft(Position k2);//左右
Position DoubleRotateWithRight(Position K2);//右左
int Max(int a,int b);
#endif
#include "AVLTree.h"
#include <stdio.h>
#include <stdlib.h>
int Max(int a,int b)
{
if(a>b)
return a;
else
return b;
}
struct AvlNode
{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Heihgt;
};
AvlTree MakeEmpty(AvlTree& T)
{
if(T!=NULL)
{
T->Left=NULL;
T->Right=NULL;
// MakeEmpty(T->Left);
//MakeEmpty(T->Right);
free(T);
T=NULL;
}
return NULL;
}
int GetHeight(Position P)
{
if(P==NULL)
return -1;
else
return P->Heihgt;
}
Position Find(ElementType X,AvlTree T)
{
if(T==NULL)
return NULL;
else if(X<T->Element)
return Find(X,T->Left);
else if(X>T->Element)
return Find(X,T->Right);
else
return T;
}
Position FindMin(AvlTree T)
{
if(T==NULL)
return NULL;
else if(T->Left==NULL)
return T;
else
return FindMin(T->Left);
}
Position FindMax(AvlTree T)
{
if(T==NULL)
return NULL;
else if(T->Right==NULL)
return T;
else
return FindMax(T->Right);
}
AvlTree Insert(ElementType X,AvlTree& T)
{
if(T==NULL)
{
T=(AvlTree)malloc(sizeof(struct AvlNode));
if(T==NULL)
printf("out of space \n");
else
{
T->Element=X;
T->Heihgt=0;
T->Left=NULL;
T->Right=NULL;
}
}
else if(X<T->Element)
{
T->Left=Insert(X,T->Left);
if(GetHeight(T->Left)-GetHeight(T->Right)==2)//需要调整恢复平衡
if(X<T->Left->Element)//左左
T=SingleRotateWithLeft(T);
else //左右
T=DoubleRotateWithLeft(T);
}
else if(X>T->Element)
{
T->Right=Insert(X,T->Right);
if(GetHeight(T->Right)-GetHeight(T->Left)==2)//需要调整恢复平衡
if(X>T->Right->Element)//右右
T=SingleRotateWithRight(T);
else //右左
T=DoubleRotateWithRight(T);
}
T->Heihgt=Max(GetHeight(T->Left),GetHeight(T->Right))+1;
return T;
}
//该删除函数 只做到了正确删除目标节点功能,但没有处理删除导致的树平衡被破坏的情况
AvlTree Delete(ElementType X,AvlTree T)//返回被删除位置新节点的指针
{
Position TemCell;
if(T==NULL)
printf("Element is not find \n");
else if(X<T->Element)
{
T->Left=Delete(X,T->Left);
}
else if(X>T->Element)
{
T->Right=Delete(X,T->Right);
}
else//找到目节点
{
if(T->Left && T->Right)//有两个儿节点
{
TemCell=FindMin(T->Right);
T->Element=TemCell->Element;
T->Right=Delete(TemCell->Element,T->Right);
}
else//注:最终被删除的节点为:单子节点或叶节点
{
TemCell=T;
if(T->Left==NULL)
{
T=T->Right;
}
else if(T->Right==NULL)
{
T=T->Left;
}
free(TemCell);
}
}
return T;
}
//前序遍历AVLTree
void PPrintTree(AvlTree T)
{
if(T==NULL)
return;
printf("%d ",T->Element);
PPrintTree(T->Left);
PPrintTree(T->Right);
}
//后序遍历AVLTree
void LPrintTree(AvlTree T)
{
if(T!=NULL)
{
LPrintTree(T->Left);
LPrintTree(T->Right);
printf("%d ",T->Element);
}
}
//中序遍历AVLTree
void MPrintTree(AvlTree T)
{
if(T!=NULL)
{
MPrintTree(T->Left);
printf("%d ",T->Element);
MPrintTree(T->Right);
}
}
//单旋转 返回新根节点
Position SingleRotateWithLeft(Position K2)//左左
{
Position K1;
K1=K2->Left;
K2->Left=K1->Right;
K1->Right=K2;
K2->Heihgt=Max(GetHeight(K2->Left),GetHeight(K2->Right))+1;
K1->Heihgt=Max(GetHeight(K1->Left),GetHeight(K1->Right))+1;
return K1;
}
Position SingleRotateWithRight(Position K2)//右右
{
Position K1;
K1=K2->Right;
K2->Right=K1->Left;
K1->Left=K2;
K2->Heihgt=Max(GetHeight(K2->Left),GetHeight(K2->Right))+1;
K1->Heihgt=Max(GetHeight(K1->Left),GetHeight(K1->Right))+1;
return K1;
}
//双旋转 返回新的根节点
Position DoubleRotateWithLeft(Position K2)//左右
{
K2->Left=SingleRotateWithRight(K2->Left);
return SingleRotateWithLeft(K2);
}
Position DoubleRotateWithRight(Position K2)//右左
{
K2->Right=SingleRotateWithLeft(K2->Right);
return SingleRotateWithRight(K2);
}