平衡二叉树 ——AVL(Adelson-Velskii Landis)
每个节点的左子树和右子树的高度最高差1的二叉查找树。
旋转
单旋转
1. 对A的左儿子的左子树进行插入——旋转左儿子往右单旋转,
2. 对A的右儿子的右子树进行插入——旋转右儿子往左单旋转
双旋转:
1. 对A的左儿子的右子树进行插入——右子树先往左旋转,左儿子再往右旋转
2. 对A的右儿子的左子树进行插入——左子树先往右旋转,右儿子再往左旋转
数据结构
typedef struct AVLTreeNode {
int value;
int height;
struct AVLTreeNode *left;
struct AVLTreeNode *right;
} AVLTreeNode;
右旋转
结点B作为A的左儿子:A比B大,因此A也可以作为B的右儿子
结点D作为B的右儿子:D比B大,D,B都比A小,所以D可以作为A的左儿子
/*
* rotate toward right
*/
AVLTreeNode *RightRotation(AVLTreeNode *avlTreeRoot)
{
AVLTreeNode *avlTreeNode = avlTreeRoot->left;
avlTreeRoot->left = avlTreeNode->right;
avlTreeNode->right = avlTreeRoot;
return avlTreeNode;
}
/*
* rotate left tree
*/
AVLTreeNode *SingleRotateWithLeft(AVLTreeNode *avlTreeRoot)
{
AVLTreeNode *avlTreeNode = avlTreeRoot->left;
avlTreeRoot->left = avlTreeNode->right;
avlTreeNode->right = avlTreeRoot;
return avlTreeNode;
}
左旋转
/*
* rotate toward left
*/
AVLTreeNode *LeftRotation(AVLTreeNode *avlTreeRoot)
{
AVLTreeNode *avlTreeNode = avlTreeRoot->right;
avlTreeRoot->right = avlTreeNode->left;
avlTreeNode->left = avlTreeRoot;
return avlTreeNode;
}
/*
* rotate right tree
*/
AVLTreeNode *SingleRotationWithRight(AVLTreeNode *avlTreeRoot)
{
AVLTreeNode *avlTreeNode = avlTreeRoot->right;
avlTreeRoot->right = avlTreeNode->left;
avlTreeNode->left = avlTreeRoot;
return avlTreeNode;
}
A的右儿子的左子树——右左双旋转
先对左子树向右旋转
再对右结点进行向左旋转
/*
* rotate left tree toward right first,
* then rotate right node toward left
*/
AVLTreeNode *RightLeftRotation(AVLTreeNode *avlTreeRoot)
{
avlTreeRoot->right = RightRotation(avlTreeRoot->right);
return LeftRotation(avlTreeRoot);
}
/*
* rotate right tree
*/
AVLTreeNode *DoubleRotateWithRight(AVLTreeNode *avlTreeRoot)
{
avlTreeRoot->right = SingleRotateWithLeft(avlTreeRoot->right);
return SingleRotateWithRight(avlTreeRoot);
}
A左儿子的右子树——左右双旋转
/*
* rotate right tree toward left first,
* then rotate left node toward right
*/
AVLTreeNode *LeftRightRotation(AVLTreeNode *avlTreeRoot)
{
avlTreeRoot->left = LeftRotation(avlTreeRoot->left);
return RightRotation(avlTreeRoot);
}
/*
* rotate left tree
*/
AVLTreeNode *DoubleRotateWithRight(AVLTreeNode *avlTreeRoot)
{
avlTreeRoot->left = SingleRotateWithRight(avlTreeRoot->left);
return SingleRotateWithLeft(avlTreeRoot);
}