//O(logn) protected bool TryFindRangeData(TNode node, RangePredicator <TEl> rangePredicator, out TRange data) { var rangeCompliant = rangePredicator.RangeCompliance(node.Min, node.Max); if (rangeCompliant == 1) { data = node.SubtreeData; return(true); } if (rangeCompliant == -1) { data = default(TRange); return(false); } TRange leftData = default(TRange), rightData = default(TRange), descendantsData = default(TRange); var leftFound = node.Left != null && TryFindRangeData(node.Left, rangePredicator, out leftData); var rightFound = node.Right != null && TryFindRangeData(node.Right, rangePredicator, out rightData); //descendant data if (!leftFound && rightFound) { descendantsData = rightData; } else if (!rightFound && leftFound) { descendantsData = leftData; } else if (leftFound && rightFound) { descendantsData = RangeConsolidator(leftData, rightData); } var nodeCompliant = rangePredicator.RangeCompliance(node.Element, node.Element) == 1; //final data if (nodeCompliant) { if (!leftFound && !rightFound) { data = node.NodeData; } else { data = RangeConsolidator(node.NodeData, descendantsData); } } else { if (!leftFound && !rightFound) { data = default(TRange); return(false); } data = descendantsData; } return(true); }
public bool TryFindRangeData(RangePredicator <TEl> rangePredicator, out TRange data) { return(TryFindRangeData(Root, rangePredicator, out data)); }