Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performing Breadth First Search recursively

Let's say you wanted to implement a breadth-first search of a binary tree recursively. How would you go about it?

Is it possible using only the call-stack as auxiliary storage?

like image 420
Nate Avatar asked Mar 31 '10 00:03

Nate


People also ask

Can you implement breadth first search recursively?

It's possible to run BFS recursively without any data structures, but with higher complexity. DFS, as opposed to BFS, uses a stack instead of a queue, and so it can be implemented recursively.

Can DFS be done recursively?

The DFS algorithm is a recursive algorithm that uses the idea of backtracking. It involves exhaustive searches of all the nodes by going ahead, if possible, else by backtracking.

Can you do BFS without queue?

Breadth-first search is a graph traversal algorithm which traverse a graph or tree level by level. In this article, BFS for a Graph is implemented using Adjacency list without using a Queue.


2 Answers

(I'm assuming that this is just some kind of thought exercise, or even a trick homework/interview question, but I suppose I could imagine some bizarre scenario where you're not allowed any heap space for some reason [some really bad custom memory manager? some bizarre runtime/OS issues?] while you still have access to the stack...)

Breadth-first traversal traditionally uses a queue, not a stack. The nature of a queue and a stack are pretty much opposite, so trying to use the call stack (which is a stack, hence the name) as the auxiliary storage (a queue) is pretty much doomed to failure, unless you're doing something stupidly ridiculous with the call stack that you shouldn't be.

On the same token, the nature of any non-tail recursion you try to implement is essentially adding a stack to the algorithm. This makes it no longer breadth first search on a binary tree, and thus the run-time and whatnot for traditional BFS no longer completely apply. Of course, you can always trivially turn any loop into a recursive call, but that's not any sort of meaningful recursion.

However, there are ways, as demonstrated by others, to implement something that follows the semantics of BFS at some cost. If the cost of comparison is expensive but node traversal is cheap, then as @Simon Buchan did, you can simply run an iterative depth-first search, only processing the leaves. This would mean no growing queue stored in the heap, just a local depth variable, and stacks being built up over and over on the call stack as the tree is traversed over and over again. And as @Patrick noted, a binary tree backed by an array is typically stored in breadth-first traversal order anyway, so a breadth-first search on that would be trivial, also without needing an auxiliary queue.

like image 176
Tanzelax Avatar answered Sep 23 '22 01:09

Tanzelax


If you use an array to back the binary tree, you can determine the next node algebraically. if i is a node, then its children can be found at 2i + 1 (for the left node) and 2i + 2 (for the right node). A node's next neighbor is given by i + 1, unless i is a power of 2

Here's pseudocode for a very naive implementation of breadth first search on an array backed binary search tree. This assumes a fixed size array and therefore a fixed depth tree. It will look at parentless nodes, and could create an unmanageably large stack.

bintree-bfs(bintree, elt, i)     if (i == LENGTH)         return false      else if (bintree[i] == elt)         return true      else          return bintree-bfs(bintree, elt, i+1)         
like image 20
Patrick McMurchie Avatar answered Sep 23 '22 01:09

Patrick McMurchie