Consider the following tree:

You start with traverse(1)
:
traverse(1)

And after "mark 1" the method will start looping over all child nodes, calling traverse
for each. The first, traverse(1.1)
, will "barge in on the execution":
traverse(1)
traverse(1.1)

As traverse(1.1)
hits "mark 1", it will start to proceed its children and call traverse(1.1.1)
:
traverse(1)
traverse(1.1)
traverse(1.1.1)

Since "1.1.1" does not have any children, traverse(1.1.1)
reaches "mark 2" and the execution flow will return to the forEach
loop of the parent method traverse(1.1)
:
traverse(1)
traverse(1.1)

The loop continues and traverse
will be called for the second child, "1.1.2":
traverse(1)
traverse(1.1)
traverse(1.1.2)

After both children of "1.1" have been processed, traverse(1.1)
reaches "mark 2" and the execution flow is now back in the forEach
loop of traverse(1)
:
traverse(1)

Proceeding with "1.2":
traverse(1)
traverse(1.2)

I'll stop here, but you should get the hang of it. What you can see is that "1.1.1" and "1.1.2" are visited before "1.2", making it a depth-first search. A breadth-first search would visit "1.2" and "1.3" before "1.1.1".