So my mind is stuck right now and I can't seem to convert a tail-recursive (I think) tree printing function to a recursive equivalent. It is supposed to print something like:
try Googling for:
"iterative tree traversal"
you might want to add one of the following terms:
in-order, pre-order, post-order, breadth-first etc
Most (all?) of the iterative methods I remember seeing use a stack to keep track. You can use a large-enough (over-sized) fixed-size array to hold a simulated stack, but I do not know if that approach will help you at all.
Thanks for the suggestions. I thought it may be a tail recursive function , which doesn't need a stack, but I now see it is not. That forces me to use a stack for depth first traversal to print in that format. Breadth first traversal generates a bad tree format and still requires a queue data structure.
Problem is I am doing this on a gpu that don't support recursion and don't have stl. I don't want to implement a stack just for printing output. I managed to avoid recursion everywhere else but here.I guess I will have to copy the tree back to the cpu and use the recursive version there.
I can't believe it but I may have found a solution without using a stack. It uses three (!) loops to do a depth first traversal. It is better to explain it by code so here it goes:
__global__
void printTree() {
Node* current = root_node;
while(current) {
while(current) {
while(current) {
PRINT_WITH_FORMAT();
//child
if(current->child) current = current->child;
else break;
}
//sibling
if(current->next) current = current->next;
else break;
}
//parent
if(current->parent) current = current->parent->next;
else break;
}
}
Caution at the outer loop during backing up. We go to the parent and the sibling at once (two commands unlike the single one in the inner loops). Please let me know if you find problem with it. I have printed a tree with it but I am still not sure if it is bug free.
Edit: Yep it works correctly. I have modified it further to get the depth of the tree at any node. The width is a bit difficult because of that back up step I mentioned above. The width should be stored in a stack to resume where we left of before. Actually for my case I can calculate it indirectly from the address of contigious blocks of siblings but that is a hack. So the modified working code for depth changes and depth limit is:
void PrintSubTree (Node* current)
{
Node* parent = current->parent;
while (current != parent)
{
if (current->child)
current = current->child;
else do
{
if (current->next)
{
current = curent->next;
break;
}
curent = curent->parent;
} while (curent != parent);
}
}
Daniel Shawul wrote:There was a bug in backing up. It was only printing a segment of the whole tree. Now it required a goto. Maybe that can be avoided somehow..