I have a perfect balanced binary tree:
1
/ \
2 5
/ \ / \
3 4 6 7
A simple node structure with DF traversal:
function TreeNode(val){
this.val = val
this.left = this.right = null
this.addLeft = function(node){
this.left = node
}
this.addRight = function(node){
this.right = node
}
}
function visit(node){
console.log(node.val)
}
function traverse(node){
if (node == null) return
visit(node)
if(node.left){
traverse(node.left)
}
if(node.right){
traverse(node.right)
}
}
I create nodes to represent a tree structure:
let rootNode = new TreeNode(1)
let node_A = new TreeNode(2)
let node_B = new TreeNode(5)
let node_C = new TreeNode(3)
let node_D = new TreeNode(4)
let node_E = new TreeNode(6)
let node_F = new TreeNode(7)
rootNode.addLeft(node_A)
rootNode.addRight(node_B)
node_A.addLeft(node_C)
node_A.addRight(node_D)
node_B.addLeft(node_E)
node_B.addRight(node_F)
Calling traverse(rootNode)
prints out correctly:
1
2
3
4
5
6
7
I understand how recursion works, but am still a little bit confused how JavaScript handles it in the call stack. traverse(rootNode)
is put in the call stack first, then it reaches the if condition, inside here it checks that rootNode
has a node left, so it continues down the path until it reaches the final node, which is TreeNode(3)
. The call stack is like this:
| |
| |
| traverse(TreeNode(3)) |
| traverse(TreeNode(2)) |
| traverse(rootNode) |
|_____________________________| |
TreeNode(3)
does not have any node.left
or node.right
so it returns to the if condition, and goes down to check node.right
, the second condition. Then it sees indeed TreeNode(2)
has a node.right
and traverse to TreeNode(4)
and push it to the stack.
Now this part is confusing me. How does JavaScript keep track of calling rootNode.right
when traverse(TreeNode(4)
is completed? In other words, how does it know to switch to the right branch at the end of left branch? Because the output prints 1
to 7
, so the call stack must be:
| |
| traverse(TreeNode(7)) |
| traverse(TreeNode(6)) |
| traverse(TreeNode(5)) |
| traverse(TreeNode(4)) |
| traverse(TreeNode(3)) |
| traverse(TreeNode(2)) |
| traverse(rootNode) |
|_____________________________|
But I believe the top of the stack will be the first to pop out and return, so the output should be starting from 7
, not 1
. So my second question is why the console log correctly prints out the result from 1
to 7
.