问题
How can I traverse an n
-ary tree without using recursion?
Recursive way:
traverse(Node node)
{
if(node == null)
return;
for(Node child : node.getChilds()) {
traverse(child);
}
}
回答1:
You can do this without recursion and without a stack. But you need to add two extra pointers to the node:
- The parent node. So you can come back to the parent if you are finished.
The current child node so you know which one to take next.
- For each node, you handle all the kids.
- If a kid is handled, you check if there is a next kid and handle that (updating the current).
- If all kids are handled, go back to the parent.
- If the node is NULL, quit.
With pseudocode this looks like:
traverse(Node node) {
while (node) {
if (node->current <= MAX_CHILD) {
Node prev = node;
if (node->child[node->current]) {
node = node->child[node->current];
}
prev->current++;
} else {
// Do your thing with the node.
node->current = 0; // Reset counter for next traversal.
node = node->parent;
}
}
}
回答2:
What you are doing is essentially a DFS of the tree. You can eliminate recursion by using a stack:
traverse(Node node) {
if (node==NULL)
return;
stack<Node> stk;
stk.push(node);
while (!stk.empty()) {
Node top = stk.pop();
for (Node child in top.getChildren()) {
stk.push(child);
}
process(top);
}
}
If you want a BFS use a queue:
traverse(Node node) {
if (node==NULL)
return;
queue<Node> que;
que.addRear(node);
while (!que.empty()) {
Node front = que.deleteFront();
for (Node child in front.getChildren()) {
que.addRear(child);
}
process(front);
}
}
In case you want some other way to traverse, you'll have to follow the same approach albeit with a different data structure to store the node. Maybe a priority queue (if you want to evaluate a function at each node and then process nodes based on that value).
回答3:
No language given, so in pseudo-pseudocode:
traverse(Node node)
{
List<Node> nodes = [node];
while (nodes.notEmpty) {
Node n = nodes.shift();
for (Node child in n.getChildren()) {
nodes.add(child);
}
// do stuff with n, maybe
}
}
Note that this is a breadth-first traversal as opposed to the depth-first traversal given in the question. You should be able to do a depth-first traversal by pop
ing the last item off the nodes
list instead of shift
ing the first one.
来源:https://stackoverflow.com/questions/5987867/traversing-a-n-ary-tree-without-using-recurrsion