AVL树的插入、创建和删除。主要是参考中国大学MOOC浙大版数据结构。
#include<bits/stdc++.h>
using namespace std;
/*
AVL基本操作:
00)插入
01)创建
02)删除
*/
/*
AVL:
1)是一棵空树
2)具有下列性质的二叉树:
1)若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉排序树。
2)每个结点的左右子树高度差最大为 1
特点:
树高为log2(n)
*/
/*
四种旋转
1)单左旋转:
破坏者在被破坏者(A)左孩子(B)的左子树上:B上升、A下沉、B右挂在A左上
A->left = B->right; B->right = A;
2)单右选择:
破坏者在被破坏者(A)右孩子(B)的右孩子上:B上升、A下沉、B左挂在A右上
A->right = B->left; B->left = A;
3)左右旋转:
破坏者在被破坏者(A)左孩子(B)的右子树上:
B做单右旋转; A做单左旋转;
4)右左旋转:
破坏者在被破坏者(A)右孩子(B)的左子树上:
B做单左旋转; A做单右旋转;
*/
//AVL结点结构
typedef class Node
{
public:
int val;
Node *left;
Node *right;
int height;
Node(){ left = right = NULL; }
Node(int tval){ val = tval; left = right = NULL; }
} *AVL;
/*
单左旋转:
破坏者在被破坏者(A)左孩子(B)的左子树上:B上升、A下沉、B右挂在A左上
A->left = B->right; B->right = A;
必须保证 A有左子树
*/
AVL singleLeftRotation(AVL root)
{
AVL rl = root->left;
root->left = rl->right;
rl->right = root;
return rl;
}
/*
单右旋转
破坏者在被破坏者(A)右孩子(B)的右孩子上:B上升、A下沉、B左挂在A右上
A->right = B->left; B->left = A;
必须保证 A有右子树
*/
AVL singleRightRotation(AVL root)
{
AVL rr = root->right;
root->right = rr->left;
rr->left = root;
return rr;
}
/*
左右旋转
破坏者在被破坏者(A)左孩子(B)的右子树上:
B做单右旋转; A做单左旋转;
必须保证 A的左孩子和B的右孩子存在
*/
AVL leftRightRotation(AVL root)
{
root->left = singleRightRotation(root->left);
return singleLeftRotation(root);
}
/*
右左旋转
破坏者在被破坏者(A)右孩子(B)的左子树上:
B做单左旋转; A做单右旋转;
*/
AVL rightLeftRotation(AVL root)
{
root->right = singleLeftRotation(root->right);
return singleLeftRotation(root);
}
/*
插入
1)root为空时,插入结点
2)root的值小于插入的值时:
递归到右子树
退栈时如果 右子树的高度 - 左子树的高度 == 2:
插入右子树的左子树时,右左旋转
插入右子树的右子树时,单右旋转
3)root的值大于插入的值时:
递归到左子树
退栈时如果 左子树的高度 - 右子树的高度 == 2:
插入左子树的左子树时,单左旋转
插入左子树的右子树时,左右旋转
4)更新 root的高度
*/
int getHeight(Node *node){ return node == NULL ? 0 : node->height; }
AVL insert(AVL root, Node* node)
{
if(root == NULL)
root = node;
else if(root->val < node->val){
root->right = insert(root->right, node); //出来之后 root->right一定不为空
if(getHeight(root->right) - getHeight(root->left) == 2)
if(node->val < root->right->val)
root = leftRightRotation(root);
else
root = singleRightRotation(root);
}
else if(root->val > node->val){
root->left = insert(root->left, node);
if(getHeight(root->left) - getHeight(root->right) == 2)
if(node->val < root->right->val)
root = singleLeftRotation(root);
else
root = rightLeftRotation(root);
}
root->height = max(getHeight(root->left), getHeight(root->right)) + 1;
}
AVL create()
{
int n, val;
cin >> n;
AVL root = NULL;
for(int i = 0; i < n; i++)
{
cin >> val;
root = insert(root, new Node(val));
}
return root;
}
/*
删除
1)root的值等于需删除的值时:右子树最小值替换root值,删除原右子树最小值
2)root的值为空时:返回root
3)root的值大于需删除的值时:递归左子树,退栈时若 右子树的高 - 左子树的高 == 2,判断右子树确定旋转方式
4)root的值小于需删除的值时:递归左子树,退栈时若 左子树的高 - 右子树的高 == 2,判断左子树确定旋转方式
*/
AVL del(AVL root, int val)
{
if(root == NULL)
return root;
else if(root->val < val){
root->right = del(root->right, val); //递归右子树
if(getHeight(root->left) - getHeight(root->right) == 2)
{
AVL temp = root->left;
//temp的左子树高于右子树时:单左旋转
//temp的右子树高于左子树时:左右旋转
if(getHeight(temp->left) > getHeight(temp->right))
root = singleLeftRotation(root);
else
root = leftRightRotation(root);
}
}else if(root->val > val){
root->left = del(root->left, val);
if(getHeight(root->right) - getHeight(root->left) == 2)
{
AVL temp = root->right;
//temp的左子树高于右子树时:右左旋转
//temp的右子树高于左子树时:单右旋转
if(getHeight(temp->left) > getHeight(temp->right))
root = rightLeftRotation(root);
else
root = singleRightRotation(root);
}
}else{
//若左子树为空,右子树上升;右子树为空,左子树上升
//左右都不空时:用右子树最小值替换根的值,递归右子树删除原右子树最小值
if(root->left == NULL || root->right == NULL)
return root->left == NULL ? root->right : root->left;
AVL temp = root->right;
while(temp->left != NULL)
temp = temp->left;
root->val = temp->val;
root->right = del(root->right, root->val);
return root;
}
//更新这次删除造成的高度的改变
root->height = max(getHeight(root->right), getHeight(root->left)) + 1;
}
void print_levelOrder_noLayered(AVL root)
{
AVL pointer = root;
int f = 0, t = 0; //头、尾。模拟队列
AVL arr[1010];
if(pointer != NULL)
arr[t++] = pointer;
while(t > f)
{
pointer = arr[f++];
cout << pointer->val;
if(pointer->left != NULL)
arr[t++] = pointer->left;
if(pointer->right != NULL)
arr[t++] = pointer->right;
}
}
int main()
{
AVL root = create();
print_levelOrder_noLayered(root);
cout << endl;
AVL d = del(root, 2);
print_levelOrder_noLayered(d);
return 0;
}
/*
input:
5
2 4 1 3 0
AVL:
2
1 4
0 3
*/