Given the following algorithm:
This is a solution using two stacks.
Suppose we always compute right child before left child, we need a way to store the result of right child. It's possible to store it on the original stack but it would be complicated since that stack is used to compute left child too. So I use another stack to store those results of right children.
There are three status:
When it sees a node with status finish work
, it will check if the next
node's status is need merge
:
finish work
console.log(JSON.stringify(create(2, 5), null, 2))
function Klass(i, l, r) {
this.i = i;
this.l = l;
this.r = r;
}
function create(i, growto) {
var stack = [];
var cache = [];
stack.push([i, 'need work']);
while (stack.length && stack[0][1] !== 'finish work') {
var cur = stack.pop();
var val = cur[0];
var status = cur[1];
if (status === 'need work') {
if (val !== growto) {
stack.push([val, 'need merge']);
stack.push([val + 1, 'need work']);
stack.push([val + 1, 'need work']);
} else {
stack.push([val, 'finish work']);
}
} else if (status === 'finish work') {
if (stack[stack.length - 1][1] !== 'need merge') {
cache.push(cur);
} else {
var root = stack.pop()[0];
var left = cur[0];
var right = cache.pop()[0];
stack.push([new Klass(root, left, right), 'finish work']);
}
}
}
return stack.pop()[0];
}