public static NodeClosures Analyse(Node root) { var results = new NodeClosures { AncestorClosures = new Dictionary<int, HashSet<int>>(), DescendantClosures = new Dictionary<int, HashSet<int>>() }; //walk the tree and build the closures lists var stack = new Stack<Node>(); stack.Push(root); var route = new Stack<Node>(); while (stack.Count != 0) { var current = stack.Pop(); while (route.Any() && !route.Peek().Children.Any(n => n.Id == current.Id)) { route.Pop(); } route.Push(current); AddNodeRelationships(results, current, route); foreach (var child in current.Children) { stack.Push(child); } } return results; }
private static void AddNodeRelationships(NodeClosures results, Node current, IEnumerable<Node> route) { foreach (var node in route) { results.AncestorClosures.GetOrCreateValuesList(current.Id).Add(node.Id); results.DescendantClosures.GetOrCreateValuesList(node.Id).Add(current.Id); } }