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.
console.log('I have returned to node '+ node.val);immediately after each of your traversal method calls. jsfiddle.net/0zy3fq92/1traversefunction even before the base return condition, and it still prints out correctly from1to7.