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 */