A | +--B | +--C | | | +--D | +--EResult:
{ A, B, C, D, E }
Data structure:
node:
string name
list<node> children
Using recursion:
traverse(root):
list = new
Get(root, list)
return list
// with list
Get(node, list):
list.add(node)
if node.children == null:
return
foreach child in node.children:
Get(child, list)
Using recursion and yield return:
traverse(root):
return Get(root)
// with yield return
Get(node):
yield return node
if node.children == null:
yield break
foreach child in node.children:
foreach n in Get(child):
yield return n
But it is inefficient when the tree is deep as every method call creates an iterator (see this), i.e. O(n) iterators. So the work-around is to not use recursion and save nodes in a stack with O(n) space and O(logn) iterators.
traverse(root):
return Get(root)
// without recursion, with yield return
Get(node):
stack = new
stack.push(node)
while !stack.empty():
var n = stack.pop()
yield return n
if n.children == null:
continue
// reverse to preserve children order
foreach child in n.children.reverse():
stack.push(child)
[Hat tip to RT, JS, EL]
No comments:
Post a Comment