#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
struct TreeNode{
int data;
TreeNode* lchild, *rchild;
int freq, height;
};
class AVLTree{
public:
TreeNode *head;
AVLTree(){
head = NULL;
}
void Insert(int x, TreeNode* &cur){
if(cur == NULL){
cur = new TreeNode;
cur->data = x;
cur->lchild = cur->rchild = NULL;
cur->freq = cur->height = 1;
}
else if(x < cur->data){
Insert(x, cur->lchild);
if(2 == CampHeight(cur->lchild, cur->rchild)){
if(x < cur->lchild->data) LL(cur);
else LR(cur);
}
}
else if(x > cur->data){
Insert(x, cur->rchild);
if(2 == CampHeight(cur->rchild, cur->lchild)){
if(x > cur->rchild->data) RR(cur);
else RL(cur);
}
}
else
cur->freq++;
}
void InOrder(TreeNode* t){
if(t == NULL) return;
InOrder(t->lchild);
cout << t->data << " ";
InOrder(t->rchild);
}
private:
void LL(TreeNode* t){
TreeNode* tmp = t->lchild;
t->lchild = tmp->rchild;
tmp->rchild = t;
GainHeight(t);
GainHeight(tmp);
}
void RR(TreeNode* t){
TreeNode* tmp = t->rchild;
t->rchild = tmp->lchild;
tmp->lchild = t;
GainHeight(t);
GainHeight(tmp);
}
void LR(TreeNode* t){
RR(t->lchild);
LL(t);
}
void RL(TreeNode* t){
LL(t->rchild);
RR(t);
}
void GainHeight(TreeNode* t){
if(t == NULL) return;
if(t->lchild != NULL && t->rchild != NULL)
t->height = (t->lchild->height > t->rchild->height ? t->lchild->height : t->rchild->height) + 1;
else if(t->lchild == NULL && t->rchild == NULL)
t->height = 1;
else if(t->lchild != NULL)
t->height = t->lchild->height + 1;
else
t->height = t->rchild->height + 1;
}
int CampHeight(TreeNode* p, TreeNode* q){
if(p != NULL && q != NULL)
return p->height - q->height;
else if(p == NULL && q == NULL)
return 0;
else if(p != NULL)
return p->height;
else
return -q->height;
}
};
int main(){
int arr[] = {6,7,3,5,3,2,1,78,45,65};
AVLTree tree;
for(int i = 0; i < sizeof(arr)/sizeof(int); i++){
tree.Insert(arr[i], tree.head);
}
tree.InOrder(tree.head);
cout << endl;
return 0;
}