Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Walking a tree, parent first

What is the best way to visit all the nodes of a linked tree (all nodes have references to parent and all children, root nodes have null as parent), so that no node is visited before any of its ancestors? Brownie points for non-recursive.

like image 953
George Avatar asked Oct 23 '09 22:10

George


3 Answers

Pseudo code:

NodesToVisit = some stack or some list
NodesToVisit.Push(RootNode)

While NodesToVisit.Length > 0
{
   CurNode = NodesToVisit.Pop()
   For each Child C in CurNode
        NodesToVisit.Push(C)
   Visit(CurNode) (i.e. do whatever needs to be done)
}

Edit: Recursive or not?
To be technically correct, and as pointed out by AndreyT and others in this post, this approach is a form of a recursive algorithm, whereby an explicitly managed stack is used in lieu of the CPU stack and where the recursion takes place at the level of the While loop. This said, it differs from a recursive implementation per se in a couple of subtle yet significant ways:

  • Only the "variables" are pushed onto the stack; there is no "stack frame" and associated return address on the stack, the only "return address" is implicit to the while loop, and there is but one instance of it.
  • The "stack" could be used as a list whereby the next "frame" could be taken anywhere in the list, without braking the logic in any way.
like image 74
mjv Avatar answered Sep 18 '22 15:09

mjv


Breadth First Search

like image 45
Mercurybullet Avatar answered Sep 20 '22 15:09

Mercurybullet


You're looking for a preorder traversal. I think you can do it non-recursively with a queue:. In pseudocode:

Create an empty queue, then push the root node.

while nonempty(q)
  node = pop(q)
  visit(node)
  foreach child(node)
    push(q,child)
like image 45
Jim Lewis Avatar answered Sep 21 '22 15:09

Jim Lewis