/// <summary> /// Returns a breadth first child edge iterator. /// </summary> /// <param name="treeNode">The tree node.</param> /// <param name="treeIterationMode">The tree iteration mode.</param> /// <returns>A breadth first child edge iterator.</returns> public static IEnumerable <ITaxonRelationsTreeEdge> AsBreadthFirstChildEdgeIterator( this ITaxonRelationsTreeNode treeNode, TaxonRelationsTreeChildrenIterationMode treeIterationMode) { return(AsBreadthFirstChildEdgeIterator(new List <ITaxonRelationsTreeNode> { treeNode }, treeIterationMode)); }
/// <summary> /// Returns a breadth first child edge iterator. /// </summary> /// <param name="treeNodes">The tree nodes.</param> /// <param name="treeIterationMode">The tree iteration mode.</param> /// <returns>A breadth first child edge iterator.</returns> public static IEnumerable <ITaxonRelationsTreeEdge> AsBreadthFirstChildEdgeIterator( this ICollection <ITaxonRelationsTreeNode> treeNodes, TaxonRelationsTreeChildrenIterationMode treeIterationMode) { HashSet <ITaxonRelationsTreeNode> visitedNodes = new HashSet <ITaxonRelationsTreeNode>(); HashSet <ITaxonRelationsTreeEdge> visitedEdges = new HashSet <ITaxonRelationsTreeEdge>(); Queue <ITaxonRelationsTreeEdge> queue = new Queue <ITaxonRelationsTreeEdge>(); foreach (var treeNode in treeNodes) { visitedNodes.Add(treeNode); if (treeIterationMode == TaxonRelationsTreeChildrenIterationMode.Everything) { if (treeNode.AllChildEdges != null) { for (int i = 0; i < treeNode.AllChildEdges.Count; i++) { queue.Enqueue(treeNode.AllChildEdges[i]); } } } else { if (treeNode.ValidMainChildren != null) { for (int i = 0; i < treeNode.ValidMainChildren.Count; i++) { queue.Enqueue(treeNode.ValidMainChildren[i]); } } if (treeIterationMode == TaxonRelationsTreeChildrenIterationMode.BothValidMainAndSecondaryChildren) { if (treeNode.ValidSecondaryChildren != null) { for (int i = 0; i < treeNode.ValidSecondaryChildren.Count; i++) { queue.Enqueue(treeNode.ValidSecondaryChildren[i]); } } } } } while (queue.Any()) { ITaxonRelationsTreeEdge current = queue.Dequeue(); if (current != null) { if (treeIterationMode == TaxonRelationsTreeChildrenIterationMode.Everything) { if (current.Child.AllChildEdges != null) { for (int i = 0; i < current.Child.AllChildEdges.Count; i++) { queue.Enqueue(current.Child.AllChildEdges[i]); } } } else { if (current.Child.ValidMainChildren != null) { for (int i = 0; i < current.Child.ValidMainChildren.Count; i++) { queue.Enqueue(current.Child.ValidMainChildren[i]); } } if (current.Child.ValidSecondaryChildren != null) { for (int i = 0; i < current.Child.ValidSecondaryChildren.Count; i++) { queue.Enqueue(current.Child.ValidSecondaryChildren[i]); } } } // Avoid cycles. Just return not visited nodes. if (!visitedNodes.Contains(current.Child)) { visitedNodes.Add(current.Child); } // Avoid cycles. Just return not visited edges. if (!visitedEdges.Contains(current)) { visitedEdges.Add(current); yield return(current); } } } }
/// <summary> /// Returns a depth first child edge iterator. /// </summary> /// <param name="treeNodes">The tree nodes.</param> /// <param name="treeIterationMode">The tree iteration mode.</param> /// <returns>A depth first child edge iterator.</returns> public static IEnumerable <ITaxonRelationsTreeEdge> AsDepthFirstChildEdgeIterator( this ICollection <ITaxonRelationsTreeNode> treeNodes, TaxonRelationsTreeChildrenIterationMode treeIterationMode) { HashSet <ITaxonRelationsTreeNode> visitedNodes = new HashSet <ITaxonRelationsTreeNode>(); HashSet <ITaxonRelationsTreeEdge> visitedEdges = new HashSet <ITaxonRelationsTreeEdge>(); Stack <ITaxonRelationsTreeEdge> stack = new Stack <ITaxonRelationsTreeEdge>(); foreach (var treeNode in treeNodes) { visitedNodes.Add(treeNode); if (treeNode.ValidMainChildren != null) { for (int i = treeNode.ValidMainChildren.Count - 1; i >= 0; i--) { stack.Push(treeNode.ValidMainChildren[i]); } } if (treeIterationMode == TaxonRelationsTreeChildrenIterationMode.BothValidMainAndSecondaryChildren) { if (treeNode.ValidSecondaryChildren != null) { for (int i = treeNode.ValidSecondaryChildren.Count - 1; i >= 0; i--) { stack.Push(treeNode.ValidSecondaryChildren[i]); } } } } while (stack.Any()) { ITaxonRelationsTreeEdge current = stack.Pop(); if (current != null) { if (current.Child.ValidMainChildren != null) { for (int i = current.Child.ValidMainChildren.Count - 1; i >= 0; i--) { stack.Push(current.Child.ValidMainChildren[i]); } } if (current.Child.ValidSecondaryChildren != null) { for (int i = current.Child.ValidSecondaryChildren.Count - 1; i >= 0; i--) { stack.Push(current.Child.ValidSecondaryChildren[i]); } } // Avoid cycles. Just return not visited nodes. if (!visitedNodes.Contains(current.Child)) { visitedNodes.Add(current.Child); } // Avoid cycles. Just return not visited edges. if (!visitedEdges.Contains(current)) { visitedEdges.Add(current); yield return(current); } } } }