#include <iostream>
using namespace std;
struct tree
{
int val;
int bf;
tree *Up;
tree *R;
tree *L;
};
class AVLTree
{
public:
tree *root;
AVLTree()
{
root = NULL;
}
void RR(tree *A);
void LL(tree *A);
void RL(tree *A);
void LR(tree *A);
void Add(int num);
void insertAVL(int k);
void printAVL(string sp, string sn, tree *node);
tree *Find(tree *node, int search);
void PreOrder(tree *node);
void InOrder(tree *node);
void PostOrder(tree *node);
tree *Minimum(tree *node);
tree *Maximum(tree *node);
tree *After(tree *node);
tree *Before(tree *node);
tree *BeforeImp(tree *node);
tree *Remove(tree *node);
tree *RemoveImp(tree *node);
};
void printBT(const string &prefix, const tree *node, bool isLeft)
{
if (node != nullptr)
{
cout << prefix;
cout << (isLeft ? "|--" : "L--");
cout << node->val << endl;
printBT(prefix + (isLeft ? "| " : " "), node->R, true);
printBT(prefix + (isLeft ? "| " : " "), node->L, false);
}
}
void AVLTree::printAVL(string sp, string sn, tree *node)
{
string cr, cl, cp;
cr = cl = cp = " ";
cr[0] = 218;
cr[1] = cl[1] = 196;
cl[0] = 192;
cp[0] = 179;
string s;
if (node)
{
s = sp;
if (sn == cr)
s[s.length() - 2] = ' ';
printAVL(s + cp, cr, node->R);
s = s.substr(0, sp.length() - 2);
cout << s << sn << node->val << ":" << node->bf << endl;
s = sp;
if (sn == cl)
s[s.length() - 2] = ' ';
printAVL(s + cp, cl, node->L);
}
}
tree *AVLTree::Find(tree *node, int search)
{
if (search == node->val)
return node;
else if (search < node->val)
Find(node->L, search);
else if (search > node->val)
Find(node->R, search);
}
//=========================================
void AVLTree::PreOrder(tree *node) // VLR
{
cout << node->val << ":" << node->bf << " | ";
if (node->L)
PreOrder(node->L);
if (node->R)
PreOrder(node->R);
}
void AVLTree::InOrder(tree *node) // LVR
{
if (node->L)
InOrder(node->L);
cout << node->val << ":" << node->bf << " | ";
if (node->R)
InOrder(node->R);
}
void AVLTree::PostOrder(tree *node) // LRV
{
if (node->L)
PostOrder(node->L);
if (node->R)
PostOrder(node->R);
cout << node->val << ":" << node->bf << " | ";
}
//=========================================
void AVLTree::RR(tree *A)
{
tree *B = A->L;
tree *p = A->Up;
A->L = B->R;
if (A->L != NULL)
A->L->Up = A;
B->R = A;
B->Up = p;
A->Up = B;
if (p != NULL)
if (p->L == A)
p->L = B;
else
p->R = B;
else
root = B;
if (B->bf == 1)
{
A->bf = 0;
B->bf = 0;
}
else
{
A->bf = 1;
B->bf = -1;
}
}
void AVLTree::LL(tree *A)
{
tree *B = A->R;
tree *p = A->Up;
A->R = B->L;
if (A->R != NULL)
A->R->Up = A;
B->L = A;
B->Up = p;
A->Up = B;
if (p != NULL)
if (p->L == A)
p->L = B;
else
p->R = B;
else
root = B;
if (B->bf == -1)
{
A->bf = 0;
B->bf = 0;
}
else
{
A->bf = -1;
B->bf = 1;
}
}
void AVLTree::RL(tree *A)
{
tree *B = A->R;
tree *C = B->L;
tree *p = A->Up;
B->L = C->R;
if (B->L != NULL)
B->L->Up = B;
A->R = C->L;
if (A->R != NULL)
A->R->Up = A;
C->L = A;
C->R = B;
A->Up = C;
B->Up = C;
C->Up = p;
if (p != NULL)
if (p->L == A)
p->L = C;
else
p->R = C;
else
root = C;
if (C->bf == -1)
A->bf = 1;
else
B->bf = 0;
if (C->bf == 1)
A->bf = -1;
else
B->bf = 0;
C->bf = 0;
}
void AVLTree::LR(tree *A)
{
tree *B = A->L;
tree *C = B->R;
tree *p = A->Up;
B->R = C->L;
if (B->R != NULL)
B->R->Up = B;
A->L = C->R;
if (A->L != NULL)
A->L->Up = A;
C->R = A;
C->L = B;
A->Up = C;
B->Up = C;
C->Up = p;
if (p != NULL)
if (p->L == A)
p->L = C;
else
p->R = C;
else
root = C;
if (C->bf == 1)
A->bf = -1;
else
B->bf = 0;
if (C->bf == -1)
A->bf = 1;
else
B->bf = 0;
C->bf = 0;
}
//=========================================
void AVLTree::Add(int num) // adding node to AVL tree
{
tree *e = new tree();
e->L = NULL;
e->R = NULL;
e->Up = NULL;
e->val = num;
e->bf = 0;
tree *p = root;
if (p == NULL)
root = e;
else
{
while (p)
{
if (num < p->val)
{
if (p->L == NULL)
{
p->L = e;
break;
}
p = p->L;
}
else
{
if (p->R == NULL)
{
p->R = e;
break;
}
p = p->R;
}
}
e->Up = p;
if (p->bf)
p->bf = 0;
if (p->L == e)
p->bf = 1;
else
p->bf = -1;
tree *r = p->Up;
while (r != NULL)
{
if (r->bf)
{
if (r->bf == 1)
{
if (r->R == p)
r->bf = 0;
else if (p->bf == -1)
LR(r);
else
RR(r);
}
else
{
if (r->L == p)
r->bf = 0;
else if (p->bf == 1)
RL(r);
else
LL(r);
}
break;
};
if (r->L == p)
r->bf = 1;
else
r->bf = -1;
p = r;
r = r->Up;
}
}
}
//=========================================
tree *AVLTree::Minimum(tree *node) // searching minimum below node
{
if (node != NULL)
{
tree *p = node;
while (p->L)
p = p->L;
return p;
}
}
tree *AVLTree::Maximum(tree *node) // searching maximum below node
{
if (node != NULL)
{
tree *p = node;
while (p->R)
p = p->R;
return p;
}
}
//=========================================
tree *AVLTree::After(tree *node)
{
if (node != NULL)
{
if (node->R)
return Minimum(node->R);
else
{
tree *p = node;
if (p->Up->L == p)
{
return p->Up;
}
else if (p->Up->R == p)
{
while (p->Up->R == p)
{
p = p->Up;
if (p->Up == NULL)
{
return NULL;
}
}
return p->Up;
}
}
}
}
tree *AVLTree::Before(tree *node)
{
if (node != NULL)
{
if (node->L)
return Maximum(node->L);
else
{
tree *p = node;
if (p->Up->R == p)
{
return p->Up;
}
else if (p->Up->L == p)
{
while (p->Up->L == p)
{
p = p->Up;
if (p->Up == NULL)
{
return NULL;
}
}
return p->Up;
}
}
}
}
tree *AVLTree::BeforeImp(tree *node) // improved before
{
tree *p = node;
if (p != NULL)
{
if (p->L)
{
p = p->L;
while (p->R)
p = p->R;
}
else
{
tree *r = p;
while (p && p->R != r)
{
r = p;
p = p->Up;
}
}
}
return p;
}
//=========================================
tree *AVLTree::Remove(tree *node)
{
tree *y = new tree();
bool temp;
if (node->L != NULL || node->R != NULL)
{
cout << Before(node);
y = Remove(Before(node));
temp = false;
}
else
{
if (node->L != NULL)
{
y = node->L;
node->L = NULL;
}
else
{
y = node->R;
node->R = NULL;
}
node->bf = 0;
temp = true;
}
if (y != NULL)
{
y->Up = node->Up;
y->L = node->L;
if (y->L != NULL)
y->L->Up = y;
y->R = node->R;
if (y->R != NULL)
y->R->Up = y;
y->bf = node->bf;
}
if (node->Up != NULL)
{
if (node->Up->L == node)
node->Up->L = y;
else
node->Up->R = y;
}
else
root = y;
tree *z = new tree();
if (temp == true)
{
z = y;
y = node->Up;
while (y != NULL)
{
if (y->bf == 0)
{
if (y->L == z)
y->bf = -1;
else
y->bf = 1;
return node;
}
else
{
if ((y->bf != 1 || y->L != z) && (y->bf != -1 || y->R != z))
{
tree *t = new tree();
if (y->L == z)
t = y->R;
else
t = y->L;
if (t->bf != 0)
{
if (y->bf == 1)
RR(y);
else
LL(y);
return node;
}
else
{
if (y->bf == t->bf)
{
if (y->bf == 1)
RR(y);
else
LL(y);
z = t;
y = t->Up;
continue;
}
break;
}
}
else
{
y->bf = 0;
z = y;
y = y->Up;
continue;
}
}
}
if (y->bf == 1)
LR(y);
else
RL(y);
z = y->Up;
y = z->Up;
}
return node;
}
tree *AVLTree::RemoveImp(tree *node) // improved remove
{
tree *y = new tree();
bool temp;
if (node->L && node->R)
{
y = Remove(BeforeImp(node));
temp = false;
}
else
{
if (node->L)
{
y = node->L;
node->L = NULL;
}
else
{
y = node->R;
node->R = NULL;
}
node->bf = 0;
temp = true;
}
if (y)
{
y->Up = node->Up;
y->L = node->L;
if (y->L)
y->L->Up = y;
y->R = node->R;
if (y->R)
y->R->Up = y;
y->bf = node->bf;
}
if (node->Up)
{
if (node->Up->L == node)
node->Up->L = y;
else
node->Up->R = y;
}
else
root = y;
tree *z = new tree();
if (temp)
{
z = y;
y = node->Up;
while (y)
{
if (!y->bf)
{
if (y->L == z)
y->bf = -1;
else
y->bf = 1;
break;
}
else
{
tree *t = new tree();
if ((y->bf != 1 || y->L != z) && (y->bf != -1 || y->R != z))
{
if (y->L == z)
t = y->R;
else
t = y->L;
if (!t->bf)
{
if (y->bf == 1)
RR(y);
else
LL(y);
break;
}
else if (y->bf == t->bf)
{
if (y->bf == 1)
RR(y);
else
LL(y);
z = t;
y = t->Up;
continue;
}
else
{
if (y->bf == 1)
LR(y);
else
RL(y);
z = y->Up;
y = z->Up;
}
}
else
{
y->bf = 0;
z = y;
y = y->Up;
}
}
}
}
return node;
}
//=========================================
int main()
{
AVLTree drzewo;
for (int i = 0; i < 16; i++)
drzewo.Add(i + 1);
// printBT("", drzewo.root, false);
drzewo.printAVL("", "", drzewo.root);
/*
drzewo.PreOrder(drzewo.root);
drzewo.InOrder(drzewo.root);
drzewo.PostOrder(drzewo.root);
*/
}