AVL树 左子树和右子树之间差的绝对值不超过一 ,同时他们的左右子树也一样
AVL树的左子上的值比根的值小,根的值比右子的值小
如图为一个
AVL树
AVL树的结构体定义如下
typedef int KeyType;
typedef struct AVLNode
{
AVLNode *leftchild;
AVLNode *parent;
AVLNode *rightchild;
int balance;
KeyType key;
}AVLNode;
typedef struct
{
AVLNode *head; // head not root;
int cursize;
}AVLTree;
该树结构中有左子,右子,双亲节点 同时有平衡和关键值该树有头节点
头节点为这棵树根节点的双亲节点,同时根节点也为头节点的双亲节点现在为树添加关键值
关键值为右子高度减去左子高度
为该树添加一个值,导致这个树不平衡
为了让这颗树平衡,我们开始左旋这棵树
可以看到左旋就是让这棵树根节点下移,让原先不平衡节点的右子的左子为不平衡节点的右子,不平衡节点作为其右子的左子
代码如下 图中45为不平衡节点 78为新节点
void RotateLeft(AVLNode *head,AVLNode *ptr)
{
AVLNode *newroot = ptr->rightchild;//新节点为不平衡节点的右子
newroot->parent = ptr->parent; //新节点的双亲节点为不平衡节点的双亲
ptr->rightchild = newroot->leftchild;//不平衡节点的右子为新节点的左子
if(newroot->leftchild != NULL)
{
newroot->leftchild->parent = ptr; //新节点的左子的双亲节点为不平衡节点
}
newroot->leftchild = ptr;//新节点的左子为不平衡节点
if(head->parent == ptr) // 如果头节点的双亲节点为不平衡节点
{
head->parent = newroot;//头节点的双亲节点
}
else
{
if(ptr->parent->rightchild == ptr)//如果不平衡节点的双亲节点的右子为不平衡节点
{
ptr->parent->rightchild = newroot;//不平衡节点的双亲节点的右子为新节点
}
else
{
ptr->parent->leftchild = newroot;
}
}
ptr->parent = newroot;// 3
}
右旋类似
void RotateRight(AVLNode *head,AVLNode *ptr)
{
AVLNode * newroot = ptr->leftchild;
newroot->parent = ptr->parent; //1
ptr->leftchild = newroot->rightchild;
if(newroot->rightchild != NULL)
{
newroot->rightchild->parent = ptr; //2
}
newroot->rightchild = ptr;
if(head->parent == ptr) //root
{
head->parent = newroot;
}
else
{
if(ptr->parent->leftchild == ptr)
{
ptr->parent->leftchild = newroot;
}
else
{
ptr->parent->rightchild = newroot;
}
}
ptr->parent = newroot;//3
}
如果头节点的双亲节点为原不平衡节点,让新节点为头节点 原节点是左,则新节点是左,是右则右
二叉树平衡后该关键值操作代码如下
void LeftBalance(AVLNode *head,AVLNode *ptr)
{
AVLNode *leftsub = ptr->leftchild, *rightsub = NULL;
switch(leftsub->balance)
{
case 0: cout<<"Left already balance "<<endl; break;
case -1:
ptr->balance = 0;
leftsub->balance = 0;
RotateRight(head,ptr);
break;
case 1:
rightsub = leftsub->rightchild;
switch(rightsub->balance)
{
case 1:
ptr->balance = 0;
leftsub->balance = -1;
break;
case -1:
ptr->balance = 1;
leftsub->balance = 0;
break;
case 0:
ptr->balance = 0;
leftsub->balance = 0;
break
}
rightsub->balance = 0;
RotateLeft(head,leftsub);
RotateRight(head,ptr);
break;
}
}
void RightBalance(AVLNode *head,AVLNode *ptr)
{
AVLNode *rightsub = ptr->rightchild, *leftsub = NULL;
switch(rightsub->balance)
{
case 0: break;
case 1:
RotateLeft(head,ptr);
break;
case -1:
leftsub = rightsub->leftchild;
break;
}
}
其它代码
AVLNode * Buynode()
{
AVLNode *s = (AVLNode*)malloc(sizeof(AVLNode));
if(NULL == s) exit(1);
memset(s,0,sizeof(AVLNode));
return s;
}
void Freenode(AVLNode *p)
{
free(p);
}
void Init_Tree(AVLTree *ptree)
{
if(ptree == NULL) exit(1);
AVLNode *s = Buynode();
s->leftchild = NULL;
s->rightchild = NULL;
s->parent = NULL;
s->balance = 0;
ptree->head = s;
ptree->cursize = 0;
}