I have run across this method in our code base and wonder what the Big O is. The method takes a flat list and creates a tree, assigning the Parent and Children values as it goes.
private void AddChildren(Group group, IEnumerable<Group> groups)
{
foreach (var g in groups)
{
if (g.ParentId == group.Id)
{
g.Parent = group;
group.Children.Add(g);
AddChildren(g, groups);
}
}
}
It’s been a while since I have done Big O outside of identifying straight forward n^2 (or worse) methods, but my take on it goes like this:
- We are iterating every node in the list, giving us n
- We are using a conditional to process a subset of the items being iterated. There can be multiple matches here and don’t know how to express that number, or how it modifies the recursive call to AddChildren
- We have some simple assignments, and I don’t know if that warrants a +1 modifier
- We are recursing but it’s not for every item in the enclosing iteration
Just tossing something out there so I can see if I was in the ballpark:
n + (x * n)
where x is the number of matches in the if loop.
Any thoughts on what this actually is would be great, thanks.
Observe that the recursive function is only called once per parent-child relationship. In a tree structure with n nodes, there are n – 1 such relationships, so
AddChildren()is called n times (including the initial call). In each call, the work performed by the method itself (excluding the recursive call) is O(n) due to the iteration. Hence, O(n^2) in total.You can improve the complexity to O(n) by putting all groups in a hashmap first and traverse the list once, looking up each parent node in the hashmap.