I've implemented a tree (not a binary tree, every node can have several child nodes). For every node, we can access its level in the tree, its children and its parent node.
The next phase is to implement 2 iterators for this tree but the catch is I can not save more than a constant amount of information to help complete these iterators (i.e constant space complexity).
My questions are, given a node n that I'm currently at:
- What would be the algorithm to find the next node to traverse in a BFS order?
- What would be the algorithm to find the next node to traverse in a *Reverse BFS order?
*Note:
Reverse BFS is traversing the levels in reverse order e.g Reverse BFS of the following tree
1
/ | \
2 3 4
/ / \ \
5 6 7 8
would be 5 6 7 8 then 2 3 4 and then 1.
CodePudding user response:
Here's a sketch of the algorithm. Very inefficient, but satisfies your requirement of only using O(1) additional space.
Node* GoRight(Node* c)
Ifcis root (there's no parent), returnNULL
Letpbe the parent ofc. Find its childrimmediately to the right ofc(may need to do a linear search ofp's child links). If found, returnr
If not found (cis the right-most child), setc=p, repeat from the start.
The node thus found may be at a higher level than the node we started with.
Node* GoDownToLevel(Node* p, int k)
IfpisNULL, returnNULL
Ifpis at levelk, returnp.
Starting fromp, follow the left-most child links down until levelkis reached or there are no links to follow. Letcbe the node thus found. Ifcis at levelk, returnc.
Otherwise,cis a leaf node at a level abovek. Setp = GoRight(c), repeat from the start.Node* NextAtLevel(Node* c, int k)
ReturnGoDownToLevel(GoRight(c), k)Node* NextInBFSOrder(Node* c)
Letkbe the level ofc. Letr = NextAtLevel(c, k). Ifris notNULL, returnr.
Otherwise, traverse the parent chain all the way to the root, returnGoDownToLevel(root, k 1). Alternatively,rootcould be stored in the iterator. Alternatively, the iterator could keep track of the leftmost child of the first non-leaf node it encountered while traversing levelk, and jump to that child onceNextAtLevelfails; this child starts the iteration at levelk 1.
Reverse BFS would work similarly. The hard part is finding the node to start the traversal from. Basically, perform GoDownToLevel(root, infinity) while keeping track of the deepest level encountered and the first node encountered at that level. And of course, do GoDownToLevel(root, k-1) instead of GoDownToLevel(root, k 1) when NextAtLevel fails.
If you keep track of the height h of the tree while its being built, then you can start the traversal with GoDownToLevel(root, h)
CodePudding user response:
I assume you can figure out how to do an pre-order traversal of the tree: Take the root first, then go to the first child till you hit a node with no children. Then go to the parent and find the next child after the one you came from. If it was the last child repeat with the new parent.
Do this once to find out the deepest node of the tree, or have the tree store its max depth. Then do it again stopping at the first child with that depth. Your iterator is that depth and the address of the child.
To increment the iterator keep doing pre-order traversal on the child and skip all the nodes where node->depth != depth. Each time the traversal finishes decrement depth. When depth becomes negative return end().
Note: in the pre-order traversal you can skip going down to children when node->depth == depth, go straight back to parent.
