平衡二叉树也是一种查找树,所以插入的数据也要满足左孩子比自己小,右孩子比自己大。并且要保持左右孩子的高度差不超过1.
插入分为4种情况:LL插入,RR插入,LR插入,RL插入。调整的方法4种与之分别对应:LL旋转,RR旋转,LR旋转,RL旋转。
LL插入,就是在结点的左子树的左孩子上面插入了新的数据,导致平衡性被破坏。所以进行LL旋转,以下同理
RR插入:
LR:
第一次旋转是围绕k1进行RR旋转,第二次是围绕k3进行LL旋转。
扫描二维码关注公众号,回复:
2255378 查看本文章
RL:
测试一组数,将他们插入树中,插入过程都调整成AVL树:
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef struct AVLTreeNode
{
int val;//值
int height;//高度
AVLTreeNode* left;
AVLTreeNode* right;
}*AVLTree;
int getHeight(AVLTree node)
{
if(node == nullptr)
return 0;
return node->height;
}
AVLTree LeftLeftRotation(AVLTree A)//左单旋,更新A,B的高度,返回新的根结点B
{//A必须有一个左子节点B
AVLTree B = A->left;
A->left = B->right;
B->right = A;
A->height = max(getHeight(A->left), getHeight(A->right)) + 1;
B->height = max(getHeight(B->left), A->height) + 1;
return B;
}
AVLTree RightRightRotation(AVLTree A)//右单旋,更新A,B的高度,返回新的根结点B
{//A必须有一个右子节点B
AVLTree B = A->right;
A->right = B->left;
B->left = A;
A->height = max(getHeight(A->left), getHeight(A->right)) + 1;
B->height = max(getHeight(B->right), A->height) + 1;
return B;
}
AVLTree LeftRightRotation(AVLTree A)//LR旋转
{//A必须有一个左子节点B,B有一个右子结点C
A->left = RightRightRotation(A->left);//将B,C做右单旋,C被返回
return LeftLeftRotation(A);//将A,C做左单旋,C被返回
}
AVLTree RightLeftRotation(AVLTree A)//RL旋转
{//A必须有一个右子节点B,B有一个左子结点C
A->right = LeftLeftRotation(A->right);//将B,C做左单旋,C被返回
return RightRightRotation(A);//将A,C做右单旋,C被返回
}
//将X插入AVL树T,返回调整后的AVL树
AVLTree insertion(int X, AVLTree T)
{
if(!T)//如果插入空树,新建包含一个结点的树
{
T = (AVLTree)malloc(sizeof(AVLTreeNode));
T->val = X;
T->height = 0;
T->left = T->right = nullptr;
}
else if(X < T->val)//插入T的左子树
{
T->left = insertion(X, T->left);
if(getHeight(T->left) - getHeight(T->right) == 2)
{
if(X < T->left->val)//左单旋
T = LeftLeftRotation(T);
else//左右旋转
T = LeftRightRotation(T);
}
}
else if(X > T->val)
{
T->right = insertion(X, T->right);
if(getHeight(T->left) - getHeight(T->right) == -2)
{
if(X > T->right->val)//右单旋
T = RightRightRotation(T);
else//右左旋转
T = RightLeftRotation(T);
}
}
//更新树高
T->height = max(getHeight(T->left), getHeight(T->right)) + 1;
return T;
}
//层序遍历
vector<vector<int> > print(AVLTree root)
{
vector<vector<int> > res;
if(root == nullptr)
return res;
queue<AVLTree> q;
q.push(root);
while(!q.empty())
{
vector<int> tmp;
const int len = q.size();
for(int i = 0; i < len; ++i)
{
AVLTree node = q.front();
int data = q.front()->val;
q.pop();
if(node->left)
{
q.push(node->left);
}
if(node->right)
{
q.push(node->right);
}
tmp.push_back(data);
}
res.push_back(tmp);
}
return res;
}
int main()
{
vector<int>test = { 3, 2, 1, 4, 5, 6, 7, 16, 15, 14, 13, 12, 11, 10, 8, 9 };
AVLTree root = nullptr;
for(int i = 0; i < test.size(); ++i)
{
root = insertion(test[i], root);
}
vector<vector<int> > order = print(root);
for(int i = 0; i < order.size(); ++i)
{
for(int j = 0; j < order[i].size(); ++j)
cout << order[i][j] << " ";
cout << endl;
}
return 0;
}