import
java.util.ArrayList;
import
java.util.LinkedList;
import
java.util.Queue;
class
GFG {
static
class
node {
int
weight;
int
level;
node left;
node right;
public
node(
int
w,
int
l)
{
this
.weight = w;
this
.level = l;
left = right =
null
;
}
}
static
node insert(node root,
int
n_weight,
int
n_level, Queue<node> q)
{
node n =
new
node(n_weight, n_level);
if
(root ==
null
)
root = n;
else
if
(q.peek().left ==
null
)
{
q.peek().left = n;
}
else
{
q.peek().right = n;
q.poll();
}
q.add(n);
return
root;
}
static
node createTree(ArrayList<Integer> weights,
ArrayList<Integer> levels)
{
node root =
null
;
Queue<node> q =
new
LinkedList<>();
int
n = weights.size();
for
(
int
i =
0
; i < n; i++)
{
root = insert(root, weights.get(i), levels.get(i), q);
}
return
root;
}
static
void
printNodeLevels(node root)
{
if
(root ==
null
)
return
;
Queue<node> q =
new
LinkedList<>();
q.add(root);
while
(!q.isEmpty()) {
System.out.print(q.peek().level +
" "
);
if
(q.peek().left !=
null
)
q.add(q.peek().left);
if
(q.peek().right !=
null
)
q.add(q.peek().right);
q.poll();
}
System.out.println();
}
static
int
findWeight(node root)
{
if
(root ==
null
)
return
0
;
return
root.weight + findWeight(root.left) + findWeight(root.right);
}
static
void
changeLevels(node root,
int
k)
{
if
(root ==
null
)
return
;
root.level = root.level + k;
changeLevels(root.left, k);
changeLevels(root.right, k);
}
static
void
adjustLevels(node root)
{
if
(root ==
null
)
return
;
int
w_left = findWeight(root.left);
int
w_right = findWeight(root.right);
int
w_diff = w_left - w_right;
changeLevels(root.left, -w_diff);
changeLevels(root.right, w_diff);
adjustLevels(root.left);
adjustLevels(root.right);
}
public
static
void
main(String[] args)
{
int
N =
3
;
int
nodes = (
int
) Math.pow(
2
, N) -
1
;
ArrayList<Integer> weights =
new
ArrayList<>();
for
(
int
i =
1
; i <= nodes; i++) {
weights.add(i);
}
ArrayList<Integer> levels =
new
ArrayList<>();
for
(
int
i =
0
; i < N; i++) {
for
(
int
j =
0
; j < (
int
) Math.pow(
2
, i); j++) {
levels.add(-
1
* i);
}
}
node root = createTree(weights, levels);
adjustLevels(root);
printNodeLevels(root);
}
}