private static KdTreeNode <TValue> Construct(KdTree <TValue, TField> tree, TValue[] elements, int startIndex, int endIndex, int depth, ValueLocationComparer valueLocationComparer) { var length = endIndex - startIndex + 1; if (length == 0) { return(null); } // Sort array of elements by component of chosen dimension, in ascending magnitude. valueLocationComparer.Dimension = depth % tree.dimensionality; Array.Sort(elements, startIndex, length, valueLocationComparer); // Select median element as pivot. var medianIndex = startIndex + length / 2; var medianElement = elements[medianIndex]; // Create node and construct sub-trees around pivot element. var node = new KdTreeNode <TValue>(medianElement); node.LeftChild = Construct(tree, elements, startIndex, medianIndex - 1, depth + 1, valueLocationComparer); node.RightChild = Construct(tree, elements, medianIndex + 1, endIndex, depth + 1, valueLocationComparer); return(node); }
public KdTree(IEnumerable <TValue> elements, params Func <TValue, double>[] valueSelectors) { _nrOfDimensions = valueSelectors.Length; _valueSelectors = valueSelectors; _valueComparer = new ValueLocationComparer(_valueSelectors); var elementsArray = elements.ToArray(); _root = Build(elementsArray, 0, elementsArray.Length - 1, 0); }