#include"BST.h"
#include"bin_tree.h"
#include<iostream>
#include<stdbool.h>
using namespace std;
#pragma once
#define Balanced(x) (stature((x).lchild) == stature((x).rchild))
#define BalFactor(x) (stature((x).lchild) - stature((x).rchild))
#define AVLBalanced(x) ((-2<BalFactor(x)) && (BalFactor(x)<2))
#define TALLER_CHILd(x) ( \
stature( (x)->lchild ) > stature( (x)->rchild ) ? (x)->lchild : ( \
stature( (x)->lchild ) < stature( (x)->rchild ) ? (x)->rchild : ( \
IS_LCHILD( * (x) ) ? (x)->lchild : (x)->rchild \
) \
) \
)
template<typename T>
class AVL :public BST<T>
{
public:
bin_node_posi<T> insert(const T&);
bool remove(const T&);
bin_node_posi<T> connect34(bin_node_posi<T>, bin_node_posi<T>, bin_node_posi<T>,
bin_node_posi<T>, bin_node_posi<T>, bin_node_posi<T>, bin_node_posi<T>);
bin_node_posi<T> rotate_at(bin_node_posi<T>);
};
template<typename T> bin_node_posi<T> AVL<T>::connect34(bin_node_posi<T> a, bin_node_posi<T> b, bin_node_posi<T> c,
bin_node_posi<T> t0, bin_node_posi<T> t1, bin_node_posi<T> t2, bin_node_posi<T> t3)
{
a->lchild = t0; if (t0) t0->parent = a;
a->rchild = t1; if (t1) t1->parent = a;
this->update_height(a);
c->lchild = t2; if (t2) t2->parent = c;
c->rchild = t3; if (t3) t3->parent = c;
this->update_height(c);
b->lchild = a; a->parent = b;
b->rchild = c; c->parent = b;
this->update_height(b);
return b;
}
template<typename T> bin_node_posi<T> AVL<T>::rotate_at(bin_node_posi<T> v)
{
bin_node_posi<T> p = v->parent; bin_node_posi<T> g = p->parent;
if(IS_RCHILD(*p))
if (IS_RCHILD(*v))
{
p->parent = g->parent;
return connect34(g, p, v, g->lchild, p->lchild, v->lchild, v->rchild);
}
else
{
v->parent = g->parent;
return connect34(g, v, p, g->lchild, v->lchild, v->rchild, p->rchild);
}
else
if (IS_LCHILD(*v))
{
p->parent = g->parent;
return connect34(v, p, g, v->lchild, v->rchild, p->rchild, g->rchild);
}
else
{
v->parent = g->parent;
return connect34(p, v, g, p->lchild, v->lchild, v->rchild, g->rchild);
}
}
template<typename T> bin_node_posi<T> AVL<T>::insert(const T& e)
{
bin_node_posi<T>& temp = this->search(e);
if (temp != NULL) return temp;
temp = new bin_node<T>(e, this->phit);
for (bin_node_posi<T> g = this->phit; g; g = g->parent)
{
if (!AVLBalanced(*g)) {
FROM_PARENT_TO(*g) = rotate_at(TALLER_CHILd(TALLER_CHILd(g)));
break;
}
else
this->update_height(g);
}
return temp;
}
template<typename T> bool AVL<T>::remove(const T& e)
{
bin_node_posi<T>& temp = this->search(e);
if (temp == NULL) return false;
remove_at(temp,this->phit);
for (bin_node_posi<T> g = this->phit; g; g = g->parent)
{
if (!AVLBalanced(*g)) {
g = FROM_PARENT_TO(*g) = rotate_at(TALLER_CHILd(TALLER_CHILd(g)));
this->update_height(g);
}
}
return true;
}
int main()
{
AVL<int> avl;
Visit<int> visit;
for (int i = 1; i < 12; ++i) {
for (int j = i; j <= i; ++j)
{
avl.insert(i);
}
avl.inorder_tra(visit);
}
}