My questions on above text snippet are
- Why level order traversals are not done recursively?
- How queue is used in level order traversal? Request clarification with Pseudo code will be helpful.
I think it'd actually be easier to start with the second question. Once you understand the answer to the second question, you'll be better prepared to understand the answer to the first.
How level order traversal works
I think the best way to understand how level order traversal works is to go through the execution step by step, so let's do that.
We have a tree.
We want to traverse it level by level.
So, the order that we'd visit the nodes would be A B C D E F G
.
To do this, we use a queue. Remember, queues are first in, first out (FIFO). I like to imagine that the nodes are waiting in line to be processed by an attendant.
Let's start by putting the first node A
into the queue.
Ok. Buckle up. The setup is over. We're about to start diving in.
The first step is to take A
out of the queue so it can be processed. But wait! Before we do so, let's put A
's children, B
and C
, into the queue also.
Note: A
isn't actually in the queue anymore at this point. I grayed it out to try to communicate this. If I removed it completely from the diagram, it'd make it harder to visualize what's happening later on in the story.
Note: A
is being processed by the attendant at the desk in the diagram. In real life, processing a node can mean a lot of things. Using it to compute a sum, send an SMS, log to the console, etc, etc. Going off the metaphor in my diagram, you can tell the attendant how you want them to process the node.
Now we move on to the node that is next in line. In this case, B
.
We do the same thing that we did with A
: 1) add the children to the line, and 2) process the node.
Hey, check it out! It looks like what we're doing here is going to get us that level order traversal that we were looking for! Let's prove this to ourselves by continuing the step through.
Once we finish with B
, C
is next in line. We place C
's children at the back of the line, and then process C
.
Now let's see what happens next. D
is next in line. D
doesn't have any children, so we don't place anything at the back of the line. We just process D
.
And then it's the same thing for E
, F
, and G
.
Why it's not done recursively
Imagine what would happen if we used a stack instead of a queue. Let's rewind to the point where we had just visited A
.
Here's how it'd look if we were using a stack.
Now, instead of going "in order", this new attendant likes to serve the most recent clients first, not the ones who have been waiting the longest. So C
is who is up next, not B
.
Here's where the key point is. Where the stack starts to cause a different processing order than we had with the queue.
Like before, we add C
's children and then process C
. We're just adding them to a stack instead of a queue this time.
Now, what's next? This new attendant likes to serve the most recent clients first (ie. we're using a stack), so G
is up next.
I'll stop the execution here. The point is that something as simple as replacing the queue with a stack actually gives us a totally different execution order. I'd encourage you to finish the step through though.
You might be thinking: "Ok... but the question asked about recursion. What does this have to do with recursion?" Well, when you use recursion, something sneaky is going on. You never did anything with a stack data structure like s = new Stack()
. However, the runtime uses the call stack. This ends up being conceptually similar to what I did above, and thus doesn't give us that A B C D E F G
ordering we were looking for from level order traversal.