Build
Node build(Point[] points, int depth) {
if (points.length == 0) return null;
int axis = depth % k;
Arrays.sort(points, (a, b) -> a.coords[axis] - b.coords[axis]);
int mid = points.length / 2;
Node n = new Node(points[mid], axis);
n.left = build(sub(points, 0, mid), depth + 1);
n.right = build(sub(points, mid + 1, points.length), depth + 1);
return n;
}Advertisement
Nearest neighbor search
void nearest(Node n, Point target, Best best) {
if (n == null) return;
update(best, n.point, dist(n.point, target));
int axis = n.axis;
Node first = (target.coords[axis] < n.point.coords[axis]) ? n.left : n.right;
Node second = first == n.left ? n.right : n.left;
nearest(first, target, best);
if (Math.abs(target.coords[axis] - n.point.coords[axis]) < best.dist)
nearest(second, target, best);
}Advertisement
Complexity
Build O(N log N). NN query O(log N) average, O(N) worst. Range O(N^(1-1/k) + K).
Curse of dimensionality
Effectiveness degrades as K grows. Above K ≈ 20, brute force competitive.