AVL树是一颗二叉查找树,又被称为平衡二叉树,它具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树,在AVL树中任何结点的两个子树的高度最大差别为1.
要求根据给定的序列,按照输入顺序插入AVL树。
要求:
输入
第一行输入不定长待插入数组。
输出
输出构造完毕的AVL树的先序遍历,逐元素换行。
#include <iostream>
#include<math.h>
class Node {
public:
Node(int elem_, Node* lchild_ = NULL, Node* rchild_ = NULL, Node* parent_ = NULL, int balance_ = 0)
{
_elem = elem_;
_lchild = lchild_;
_rchild = rchild_;
_parent = parent_;
_balance = balance_;
}
bool hasLeftChild() {//判断是否有左孩子结点
return _lchild != NULL;
}
bool hasRightChild() {//判断是否有右孩子结点
return _rchild != NULL;
}
bool hasParent() {//判断是否有父母结点
return _parent != NULL;
}
bool isLeftChild() {//判断是否为父母结点的左孩子结点
return _parent->_lchild == this;
}
bool isRightChild() {//判断是否为父母结点的右孩子结点
return _parent->_rchild == this;
}
public:
int _elem = 0;
int _balance = 0;
int height = -1;
Node* _lchild = NULL;
Node* _rchild = NULL;
Node* _parent = NULL;
};
class AVLtree {
public:
AVLtree(Node* root_ = NULL) {
_root = root_;
}
int height(Node*t)const
{
return t == NULL ? -1 : t->height;
}
void rotateL(Node*& root_) {//当前结点作根节点对应的子树左旋
Node* k1 = root_->_rchild;
if (k1 == nullptr)
{
k1 = root_;
root_ = root_->_lchild;
return;
}
root_->_rchild = k1->_lchild;
k1->_lchild = root_;
root_->height = fmax(height(root_->_rchild), height(root_->_lchild)) + 1;
root_ = k1;
return;
}
void rotateR(Node*& root_) {//当前结点作根节点对应的子树右旋
Node* k1 = root_->_lchild;
if (k1 == nullptr)
{
k1 = root_;
root_ = root_->_rchild;
return;
}
root_->_lchild = k1->_rchild;
k1->_rchild = root_;
root_->height = fmax(height(root_->_lchild), height(root_->_rchild)) + 1;
root_ = k1;
return;
}
void rebalance(Node*& node_) {//平衡AVL树
/*需要判断一下平衡类型,LL,RR,LR,RL*/
if (node_->_balance == 2)
{
if (height(node_->_lchild->_lchild) > height(node_->_lchild->_rchild)) //LL情况
rotateR(node_); //对危机节点进行右旋
else //也就是LR情况,
{
rotateL(node_->_lchild); //LR情况,使危机节点的左儿子先左旋
rotateR(node_);
} //再对原危机节点右旋
}
if (node_->_balance == -2)
{
if (height(node_->_rchild->_rchild) > height(node_->_rchild->_lchild)) //RR>RL
rotateL(node_);
else
{
rotateR(node_->_rchild); //RL情况,先右旋再左旋
rotateL(node_);
}
node_->height = fmax(height(node_->_lchild), height(node_->_rchild)) + 1;//更新高度
}
return;
}
void updateBalance(Node* node_) {//更新结点平衡值,保证在-1~1
node_->_balance = height(node_->_lchild) - height(node_->_rchild);
return;
}
void insert(int elem_, Node*& node_) {//插入结点
if (node_ == nullptr) //没有节点则新建一个
node_ = new Node{ elem_ };
else if (elem_ < node_->_elem) //如果新插入的节点比当前节点更小,则插入到左边,如果插入的节点更大则插入到右方
{
insert(elem_, node_->_lchild);//递归插入,此处lchild为NULLPTR,递归回去会到第一个if处,会给lchild创建一个新节点
updateBalance(node_);
if (node_->_balance == 2) //检测一次平衡值,只要不平衡,立刻调用平衡函数
rebalance(node_);
}
else if (node_->_elem < elem_)
{
insert(elem_, node_->_rchild);
updateBalance(node_);
if (node_->_balance == -2)
rebalance(node_);
}
else
;
node_->height = fmax(height(node_->_lchild), height(node_->_rchild)) + 1;
}
void pre_order(Node* node_) {//先序遍历
if (node_ != NULL) {
std::cout << node_->_elem << std::endl;
pre_order(node_->_lchild);
pre_order(node_->_rchild);
}
return;
}
public:
Node* _root = NULL;
};
int main() {
int data_in;
AVLtree avltree;
while (std::cin >> data_in) {
avltree.insert(data_in, avltree._root);
if (std::cin.get() == '\n') break;
}
avltree.pre_order(avltree._root);
return 0;
}