/*
平衡二叉树(Balanced Binary Tree)(AVL Tree)
平衡因子(Balance Factor):BF(T) = LHeight - RHeight
|BF| <= 1
调整:
1. 左子树的左边插入,LL插入:向右旋转(顺时针)。-> 为何叫做左单旋?唉,真是让人难以理解。
2. 右子树的右边插入,RR插入:向左旋转(逆时针)。
3. 左子树的右边插入,LR插入:对左子树进行逆时针旋转,再顺时针旋转。
4. 右子树的左边插入,RL插入:对右子树进行顺时针旋转,在逆时针旋转。
*/
#ifndef AVLTREE_H
#define AVLTREE_H
#include <algorithm> //std::max
using namespace std;
using T = int; //Element Type
class AVLTree {
//节点类
struct Node {
T data;
Node *left, *right;
int height;
Node(const T &data, Node* const &left=nullptr, Node* const &right=nullptr, const int &height=0):
data(data), left(left), right(right), height(height) {}
};
public:
AVLTree(); //生成一颗空树。
// ~AVLTree();
void insert(const T &data); //提供的对外接口,友好化。插入一个节点(元素)。
int printRoot() {
return root->data;
}
private:
int getHeight(Node* const &node);
void updateHeight(Node *&node);
//插入、旋转和更新树高在此函数操作。
void insertInNode(Node *&node, const T &data);
void rotateWithLeftChild(Node *&node); //LL旋转 -> 顺时针
void rotateWithRightChild(Node *&node); //RR旋转
void doubleRotateWithLeft(Node *&node); //LR旋转 -> 左子树逆时针,再顺时针。
void doubleRotateWithRight(Node *&node); //RL旋转
Node *root; //树根节点。
int nodeCnt; //树节点个数。
};
AVLTree::AVLTree():
root(nullptr),
nodeCnt(0) {}
inline
int AVLTree::getHeight(Node* const &node) {
return node == nullptr ? -1 : node->height;
}
inline
void AVLTree::updateHeight(Node *&node) {
node->height = max(getHeight(node->left), getHeight(node->right)) + 1;
}
void AVLTree::insert(const T &data) {
insertInNode(root, data);
}
void AVLTree::insertInNode(Node *&node, const T &data) {
if(node == nullptr) {
node = new Node(data);
++nodeCnt;
}
else if(data < node->data) {
insertInNode(node->left, data);
if(getHeight(node->left) - getHeight(node->right) == 2) {
if(data < node->left->data)
rotateWithLeftChild(node);
else
doubleRotateWithLeft(node);
}
}
else if(data > node->data) {
insertInNode(node->right, data);
if(getHeight(node->left) - getHeight(node->right) == -2) {
if(data > node->right->data)
rotateWithRightChild(node);
else
doubleRotateWithRight(node);
}
}
//若相同的数据存在。Duplicate; do nothing.
updateHeight(node);
}
//node 一定有一个左孩子
void AVLTree::rotateWithLeftChild(Node *&node) {
Node *tmp = node->left;
node->left = tmp->right;
tmp->right = node;
//更新树高。此时原node是tmp的右孩子,所以先更新node。
updateHeight(node);
updateHeight(tmp); //tmp->height = max(getHeight(tmp->left), node->height) + 1;
//返回新的根节点
node = tmp;
}
//node 一定有一个右孩子
void AVLTree::rotateWithRightChild(Node *&node) {
Node *tmp = node->right;
node->right = tmp->left;
tmp->left = node;
updateHeight(node);
updateHeight(tmp);
node = tmp;
}
void AVLTree::doubleRotateWithLeft(Node *&node) {
rotateWithRightChild(node->left);
rotateWithLeftChild(node);
}
void AVLTree::doubleRotateWithRight(Node *&node) {
rotateWithLeftChild(node->right);
rotateWithRightChild(node);
}
#endif // AVLTREE_H
#include <iostream>
using namespace std;
int main(void) {
AVLTree avl;
int n, data;
cin >> n;
for(int i(0); i < n; ++i) {
cin >> data;
avl.insert(data);
}
cout << avl.printRoot() << endl;
return 0;
}