< Summary

Information
Class: MoreStructures.RecImmTrees.Paths.FullyRecursiveNodeToLeafPathsBuilder
Assembly: MoreStructures
File(s): /home/runner/work/MoreStructures/MoreStructures/MoreStructures/RecImmTrees/Paths/FullyRecursiveNodeToLeafPathsBuilder.cs
Line coverage
100%
Covered lines: 16
Uncovered lines: 0
Coverable lines: 16
Total lines: 63
Line coverage: 100%
Branch coverage
100%
Covered branches: 8
Total branches: 8
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
GetAllNodeToLeafPaths(...)100%2100%
GetAllNodeToLeafPathsR()100%6100%

File(s)

/home/runner/work/MoreStructures/MoreStructures/MoreStructures/RecImmTrees/Paths/FullyRecursiveNodeToLeafPathsBuilder.cs

#LineLine coverage
 1namespace MoreStructures.RecImmTrees.Paths;
 2
 3/// <summary>
 4///     <inheritdoc/>
 5///     <br/>
 6///     Recursive implementation.
 7/// </summary>
 8/// <remarks>
 9///     <inheritdoc cref="INodeToLeafPathsBuilder" path="/remarks"/>
 10///     <para id="advantages">
 11///     ADVANTAGES AND DISADVANTAGES
 12///     <br/>
 13///     Implemented fully recursively, so limited by stack depth and usable with tree of a "reasonable" height.
 14///     </para>
 15///     <para id="algo">
 16///     ALGORITHM
 17///     <br/>
 18///     - The implementation iterates over the children, getting its node-to-leaf subpaths by calling
 19///       <see cref="GetAllNodeToLeafPaths{TEdge, TNode}(TNode)"/> recursively.
 20///       <br/>
 21///     - Then, it prepends the child and its incoming edge to each subpath of each child.
 22///       <br/>
 23///     - If the node has no child, a singleton path is returned, containing only the child and its incoming edge.
 24///     </para>
 25///     <para id="complexity">
 26///     COMPLEXITY
 27///     <br/>
 28///     - Each node is processed once and the number of node-to-leaf paths returned has an upper bound on n = number of
 29///       nodes in the tree. The length of each node-to-leaf path is also limited by n.
 30///       <br/>
 31///     - So, both Time and Space Complexity are O(n).
 32///     </para>
 33/// </remarks>
 34public class FullyRecursiveNodeToLeafPathsBuilder : INodeToLeafPathsBuilder
 35{
 36    /// <inheritdoc path="//*[not(self::remarks)]"/>
 37    /// <inheritdoc cref="FullyRecursiveNodeToLeafPathsBuilder" path="/remarks"/>
 38    public IEnumerable<TreePath<TEdge, TNode>> GetAllNodeToLeafPaths<TEdge, TNode>(TNode node)
 39        where TEdge : IRecImmDictIndexedTreeEdge<TEdge, TNode>
 40        where TNode : IRecImmDictIndexedTreeNode<TEdge, TNode> =>
 41
 1742        GetAllNodeToLeafPathsR<TEdge, TNode>(node).Select(pathNodes => new TreePath<TEdge, TNode>(pathNodes));
 43
 44    private IEnumerable<IEnumerable<KeyValuePair<TEdge, TNode>>> GetAllNodeToLeafPathsR<TEdge, TNode>(TNode node)
 45        where TEdge : IRecImmDictIndexedTreeEdge<TEdge, TNode>
 46        where TNode : IRecImmDictIndexedTreeNode<TEdge, TNode>
 6247    {
 25348        foreach (var edgeAndChild in node.Children)
 4449        {
 4450            var childToLeafPaths = GetAllNodeToLeafPathsR<TEdge, TNode>(edgeAndChild.Value);
 4451            var childPathNode = KeyValuePair.Create(edgeAndChild.Key, edgeAndChild.Value);
 4452            if (childToLeafPaths.Any())
 1553            {
 8954                foreach (var childToLeafPath in childToLeafPaths)
 2555                    yield return childToLeafPath.Prepend(childPathNode);
 956            }
 57            else
 2958            {
 2959                yield return new KeyValuePair<TEdge, TNode>[] { childPathNode };
 1460            }
 2361        }
 4162    }
 63}