Kd-Tree

A kd-tree (k-dimensional tree, Bentley 1975) is a binary space-partitioning structure for points in Rd\mathbb{R}^d that makes nearest-neighbour queries sub-linear on average. It is the default answer to “find the closest point(s)” in low-dimensional geometric data — 3D point clouds above all — and, in randomized-forest form, a practical tool for approximate matching of high-dimensional float descriptors.

Construction

Each internal node splits the point set with an axis-aligned hyperplane:

  1. Choose a splitting dimension — classically cycling through dimensions by depth (x,y,z,x,x, y, z, x, \dots), or better, the dimension of largest variance/spread of the points in the node.
  2. Choose the splitting value — typically the median coordinate, which guarantees a balanced tree of depth O(logn)O(\log n).
  3. Recurse on the two halves until nodes hold fewer than a leaf-size threshold of points.

Building costs O(nlogn)O(n \log n) with median-of-medians or presorting; the tree stores each point once.

A query q\mathbf{q} first descends to the leaf containing it (O(logn)O(\log n) comparisons) and takes the best point found there as the current candidate with distance rbestr_{\text{best}}. Then the search backtracks: at each node on the way up, the other subtree must be visited only if the splitting plane is closer than the current best, i.e., if

qks<rbest|q_k - s| < r_{\text{best}}

where qkq_k is the query’s coordinate in the node’s split dimension kk and ss the split value — geometrically, only if the hypersphere of radius rbestr_{\text{best}} around q\mathbf{q} crosses the plane. Otherwise the whole subtree is pruned. The same scheme yields k-nearest-neighbour queries (keep a heap of the best kk) and radius searches.

In low dimensions (d10d \lesssim 10), pruning is effective and the average query cost is O(logn)O(\log n).

The curse of dimensionality

As dd grows, distances concentrate — the nearest and farthest neighbours become relatively similar in distance — and the pruning sphere intersects almost every splitting plane, so the search degenerates toward a full linear scan while paying tree-traversal overhead. As a rule of thumb, exact kd-tree search needs n2dn \gg 2^d to beat brute force; SIFT’s 128 dimensions are far beyond the exact-search regime. Two remedies define modern practice:

Note that kd-trees compare raw vectors under L2 — for binary descriptors under Hamming distance, LSH or HBST are the appropriate structures.

Where kd-trees appear in SLAM

Why it matters for SLAM

Nearest-neighbour search is one of the most-executed primitives in a SLAM system — inside every ICP iteration of a LiDAR or RGB-D pipeline, inside every matching stage of a feature pipeline, inside mapping operations like normal estimation and downsampling. Knowing the kd-tree’s mechanics tells you when it is the right tool (3D points: superb; 128-D descriptors: only in approximate/forest form; binary descriptors: wrong tool) and explains the design of the libraries built on top of it (FLANN’s indexes, PCL’s search module, ikd-Tree). It is also a recurring systems bottleneck: rebuild-vs-update strategies for a growing map directly shape the architecture of real-time LiDAR odometry.