/*************************************************************************/
构建AVL树–高度平衡
通过旋转的方法,构建AVL树,InsertAVL()函数插入元素;当结点左边子树集
高时调用LeftBalance()修复AVL树,当结点右边子树集高时调用RightBalance()修复
AVL树。RotateLeft(),RotateRight()函数完成旋转过程。下面只写RightBalance()
和RotateLeft(),其他原理相同。
Leo,2006/10/9
stefzeus@163.com
/*************************************************************************/
typedef enum Boolean
{FALSE,TRUE}Boolean;
typedef enum BalanceFactor
{LH,EH,RH}BalanceFactor;
typedef struct TreeNode
{
TreeElem entry;
TreeNode *right;
TreeNode *left;
BalanceFactor bf;
}TreeNode;
/*InsertAVL:insert newnode in AVL terr starting at the root
pre: The root of the AVL tree is pointed by root, and newnode is a
new node to be inserted into the tree.
post: newnode has been inserted into the AVL tree with taller equal to
TRUE if the height of the tree has increased, FALSE otherwise.
Uses: InsertAVL() recursively, RightBalance(), LeftBalance() */
TreeNode *InsertAVL(TreeNode *root,TreeNode *NewNode,Boolean *taller)
{
if(!root)
{
root=NewNode;
root->right=root->left=NULL;
root->bf=EH;
*taller=TRUE;
}
else if( EQ(NewNode->entry.key,root->entry.key))
printf(“Duplicate key is not allowed in AVL tree.”);
else if( LT(NewNode->entry.key,root->entry.key))
{
root->left=(root->left,NewNode,taller);
if(taller) /* left subtree is taller */
switch(root->bf)
{
case LH: /* Node was left high */
root=LeftBalance(root,taller);
break;
case RH: /* Node now has balanced height */
root->bf=EH;
*taller=FALSE;
break;
case EH: /*Node is now left hight */
root->bf=LH;
break;
}
}
else{
root->right=(root->right,NewNode,taller);
if(taller)
switch(root->bf)
{
case LH: /* Node now has balanced height */
root->bf=EH;
*taller=FALSE;
break;
case RH: /* Node was right high */
root=RightBalance(root,taller);
break;
case EH; /*Node is now right hight */
root->bf=RH;
break;
}
}
return root;
}
/*RotateLeft:rotate a binary tree to the left.
pre: p is the root of the nonempty AVL subtree being rotated,
and its right child is nonemtry.
post: The right child of p becomes the new p.The old p become the
left child of the new p. */
TreeNode *RotateLeft(TreeNode *p)
{
TreeNode *rightchild=p;
if(!p)
printf(“It is impossible to rotate an empty tree in RotateLeft.”);
else if (!p->right)
printf(“It is impossible to make an empty subtree the root in “
“RotateLeft.”);
else{
rightchild=p->right;
p->right=rightchild->left;
rightchild->left=p;
}
return rightchild;
}
/*RightBalance:right balance a binary tree.
pre: A node of an AVL tree has become doubly unbalanced to the right.
post: The AVL properties have been restored.
uses: RotateBalance(),RotateLeft(). */
TreeNode *RightBalance(TreeNode *root,Boolean *taller)
{
TreeNode *rs=root->right; /* right subtree of root */
TreeNode *ls; /* left subtree of right subtree */
switch(rs->bf)
{
case RH:
root->bf=rs->bf=EH;
root=RotateLeft(root); /* single rotation left */
*taller=FALSE;
break;
case EH:
printf(“Tree is already balanced.”);
break;
case LH: /* double totation left */
ls=rs->left;
switch(rs->bf)
{
case RH:
root->bf=LH;
rs->bf=EH;
break;
case EH:
root->bf=rs->bf=EH;
break;
case LH:
root->bf=EH;
rs->bf=RH;
break;
}
ls->bf=EH;
root->right=RotateRight(rs);
root=RotateLeft(root);
*taller=FALSE;
}
return root;
}