#include<bits/stdc++.h>
using
namespace
std;
static
int
const
log32(
int
n)
{
double
const
log23 = 2.4663034623764317;
return
(
int
)
ceil
(log23 *
log
(n));
}
class
Node
{
public
:
Node *left, *right, *parent;
float
value;
Node()
{
value = 0;
left = right = parent = NULL;
}
Node (
float
v)
{
value = v;
left = right = parent = NULL;
}
};
int
storeInArray(Node *ptr, Node *arr[],
int
i)
{
if
(ptr == NULL)
return
i;
i = storeInArray(ptr->left, arr, i);
arr[i++] = ptr;
return
storeInArray(ptr->right, arr, i);
}
class
SGTree
{
private
:
Node *root;
int
n;
public
:
void
preorder(Node *);
int
size(Node *);
bool
insert(
float
x);
void
rebuildTree(Node *u);
SGTree() { root = NULL; n = 0; }
void
preorder() { preorder(root); }
Node *buildBalancedFromArray(Node **a,
int
i,
int
n);
int
BSTInsertAndFindDepth(Node *u);
};
void
SGTree::preorder(Node *node)
{
if
(node != NULL)
{
cout << node->value <<
" "
;
preorder(node -> left);
preorder(node -> right);
}
}
int
SGTree::size(Node *node)
{
if
(node == NULL)
return
0;
return
1 + size(node->left) + size(node->right);
}
bool
SGTree::insert(
float
x)
{
Node *node =
new
Node(x);
int
h = BSTInsertAndFindDepth(node);
if
(h > log32(n))
{
Node *p = node->parent;
while
(3*size(p) <= 2*size(p->parent))
p = p->parent;
rebuildTree(p->parent);
}
return
h >= 0;
}
void
SGTree::rebuildTree(Node *u)
{
int
n = size(u);
Node *p = u->parent;
Node **a =
new
Node* [n];
storeInArray(u, a, 0);
if
(p == NULL)
{
root = buildBalancedFromArray(a, 0, n);
root->parent = NULL;
}
else
if
(p->right == u)
{
p->right = buildBalancedFromArray(a, 0, n);
p->right->parent = p;
}
else
{
p->left = buildBalancedFromArray(a, 0, n);
p->left->parent = p;
}
}
Node * SGTree::buildBalancedFromArray(Node **a,
int
i,
int
n)
{
if
(n== 0)
return
NULL;
int
m = n / 2;
a[i+m]->left = buildBalancedFromArray(a, i, m);
if
(a[i+m]->left != NULL)
a[i+m]->left->parent = a[i+m];
a[i+m]->right =
buildBalancedFromArray(a, i+m+1, n-m-1);
if
(a[i+m]->right != NULL)
a[i+m]->right->parent = a[i+m];
return
a[i+m];
}
int
SGTree::BSTInsertAndFindDepth(Node *u)
{
Node *w = root;
if
(w == NULL)
{
root = u;
n++;
return
0;
}
bool
done =
false
;
int
d = 0;
do
{
if
(u->value < w->value)
{
if
(w->left == NULL)
{
w->left = u;
u->parent = w;
done =
true
;
}
else
w = w->left;
}
else
if
(u->value > w->value)
{
if
(w->right == NULL)
{
w->right = u;
u->parent = w;
done =
true
;
}
else
w = w->right;
}
else
return
-1;
d++;
}
while
(!done);
n++;
return
d;
}
int
main()
{
SGTree sgt;
sgt.insert(7);
sgt.insert(6);
sgt.insert(3);
sgt.insert(1);
sgt.insert(0);
sgt.insert(8);
sgt.insert(9);
sgt.insert(4);
sgt.insert(5);
sgt.insert(2);
sgt.insert(3.5);
printf
(
"Preorder traversal of the"
" constructed ScapeGoat tree is \n"
);
sgt.preorder();
return
0;
}