patA1066
代码的注意点:
AVL树重新平衡最核心的思想是找到离新加入的节点最近的失衡节点。
insert操作的基础是插入新节点前子树已经是一个AVL树,这是根据平衡因子判断树型的依据。
不要把BF作为node的成员变量,因为在左旋/右旋后BF的实际值就会改变,而在判断LL/LR/RR/RL型树时使用未更新的BF成员会引发错误。正确的做法是在使用平衡因子时通过左右子树的高度来计算。
一定要有getHeight函数,并用它来获取子树的高度,否则很可能会因为使用空指针造成段错误。
正确的AVL树的根节点对应的数据一定是树中所有数据的根节点,可据此判断结果是否正确。
左旋与右旋的实现中不要遗漏掉更新root和temp节点的height值。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//AVL树的节点
struct node {
int v;
int height; //以node为根节点的子树的高度
struct node* lchild;
struct node* rchild;
node(int _v) { v = _v; height = 1; lchild = rchild = NULL; }
};
const int MAX = 25;
int N;
int num[MAX] = { 0 };
struct node* Root=NULL; //树根
void input() {
cin >> N;
for (int i = 0; i < N; i++) {
cin >> num[i];
}
}
//获取当前子树的树高
int getHeight(struct node* root) {
int height = root == NULL ? 0 : root->height;
return height;
}
//更新当前子树的树高
void updateHeight(struct node* root) {
int lheight = getHeight(root->lchild);
int rheight = getHeight(root->rchild);
root->height = max(lheight, rheight) + 1;
}
//左旋
void lo(struct node* &root) {
struct node* temp = root->rchild;
root->rchild = temp->lchild;
temp->lchild = root;
updateHeight(root);
updateHeight(temp);
root = temp;
}
//右旋
void ro(struct node* &root){
struct node* temp = root->lchild;
root->lchild = temp->rchild;
temp->rchild = root;
updateHeight(root);
updateHeight(temp);
root = temp;
}
int max(int a, int b) { return a > b ? a : b; }
//计算当前结点的平衡因子BF
int getBF(struct node* root) {
return getHeight(root->lchild)-getHeight(root->rchild);
}
//向AVL树插入一个节点,注意root必须是指针的引用,这样才能起到更新的作用
void insert(struct node* &root,int v) {
//递归边界
if (root == NULL) {
root = new struct node(v);
return;
}
//转左子树
if (root->v > v) {
insert(root->lchild, v);
//更新当前子树的高度
updateHeight(root);
//递归调用结束后判断当前子树是否失衡
int BF = getBF(root); //平衡因子BF
//BF==2说明当前节点为失衡节点
if (BF == 2) {
//判断是LL还是LR
if (getBF(root->lchild) == 1) {
//LL型树,右旋
ro(root);
}
else if (getBF(root->lchild) == -1) {
//LR型树
lo(root->lchild);
ro(root);
}
}
}
//转右子树
else {
insert(root->rchild, v);
updateHeight(root);
int BF = getBF(root);
if (BF == -2) {
if (getBF(root->rchild)==-1) {
lo(root);
}
else if (getBF(root->rchild) == 1) {
ro(root->rchild);
lo(root);
}
}
}
}
//创建一棵AVL树
void create() {
for (int i = 0; i < N; i++) {
insert(Root, num[i]);
}
}
int main(void) {
input();
create();
cout << Root->v << endl;
}

浙公网安备 33010602011771号