Horje
Java Program to Construct K-D Tree

A K-D Tree (K-Dimensional Tree) is a space-partitioning data structure designed for organizing points in a K-dimensional space. It’s particularly efficient for nearest neighbor searches, range queries, and other spatial operations. Each node in the tree represents a point in K-dimensional space and a hyperplane that splits the space into two regions.

Description:

  • Root Node: The root node contains a point and a splitting dimension.
  • Splitting: At each level, the space is split along a chosen dimension (cycling through dimensions).
  • Left and Right Subtrees: Points less than the splitting value go to the left subtree, and greater/equal go to the right.
  • Leaf Nodes: Leaf nodes contain points without further splitting.

Diagram:

                   (3, 6)
               /              \
        (2, 7)              (17, 15)
       /      \              /          \
   (1, 5)  (4, 2)   (13, 15) (19, 20)

Above is a 2-D tree (2-dimensional K-D Tree)

  • Root: (3, 6)
  • The left child of the root is split on the x-coordinate, and the right child is split on the y-coordinate.
  • This pattern continues, alternating between x and y at each level.

Implementation

Node Structure:

  • A class to store point coordinates, splitting dimension, and left/right child references.

Construction:

  • Recursively split data along the median of a chosen dimension.
  • Base case: If the number of points is small, create a leaf node.

Insertion:

  • Traverse the tree based on splitting dimensions and values, inserting at the appropriate leaf.

Basic Operations and Complexities:

Nearest Neighbor Search:

  • Start at the root, traverse to the leaf containing the query point.
  • Backtrack, checking sibling nodes if they might contain closer points.
  • Average Time Complexity: O(log n)

Range Search:

  • Similar to nearest neighbor, but explore regions overlapping the query range.
  • Time Complexity: O(k + log n), where k is the number of reported points.
  • Space Complexity: O(n) due to storing all points.

Java Program to Construct K-D Tree

Java
// Java Program to Construct K-D Tree
import java.util.Arrays;

class KDTree {
    // Dimension of the space
    private static final int K = 2;

    static class Node {
        int[] point; // Array to store k dimensional point
        Node left, right; // Left and right child

        public Node(int[] arr)
        {
            // Copy the point array
            this.point = Arrays.copyOf(arr, K);
            // Initialize children
            this.left = this.right = null;
        }
    }

    Node root; // Root of the K-D Tree

    KDTree()
    {
        root = null; // Initialize the root
    }

    // Recursive method to insert a new point in the subtree
    // rooted with the given node
    Node insertRec(Node root, int[] point, int depth)
    {
        // Base case: If the tree is empty, return a new
        // node
        if (root == null) {
            return new Node(point);
        }

        // Calculate current dimension (cd) of comparison
        int cd = depth % K;

        // Compare the new point with the root on current
        // dimension and decide the left or right subtree
        if (point[cd] < root.point[cd]) {
            root.left
                = insertRec(root.left, point, depth + 1);
        }
        else {
            root.right
                = insertRec(root.right, point, depth + 1);
        }

        return root;
    }

    // Method to insert a new point in the K-D Tree
    void insert(int[] point)
    {
        root = insertRec(root, point, 0);
    }

    // Recursive method to search a point in the subtree
    // rooted with the given node
    boolean searchRec(Node root, int[] point, int depth)
    {
        // Base case: The tree is empty or the point is
        // present at root
        if (root == null) {
            return false;
        }
        if (Arrays.equals(root.point, point)) {
            return true;
        }

        // Calculate current dimension (cd)
        int cd = depth % K;

        // Compare the point with the root on current
        // dimension and decide the left or right subtree
        if (point[cd] < root.point[cd]) {
            return searchRec(root.left, point, depth + 1);
        }
        else {
            return searchRec(root.right, point, depth + 1);
        }
    }

    // Method to search a point in the K-D Tree
    boolean search(int[] point)
    {
        return searchRec(root, point, 0);
    }

    // Recursive method for range search in the subtree
    // rooted with the given node
    void rangeSearchRec(Node root, int[] lower, int[] upper,
                        int depth)
    {
        if (root == null) {
            return;
        }

        // Check if the point of root is in range
        boolean inside = true;
        for (int i = 0; i < K; i++) {
            if (root.point[i] < lower[i]
                || root.point[i] > upper[i]) {
                inside = false;
                break;
            }
        }

        // If the point is in range, print it
        if (inside) {
            System.out.println(Arrays.toString(root.point));
        }

        // Calculate current dimension (cd)
        int cd = depth % K;

        // Check subtrees if they can have points within the
        // range
        if (lower[cd] <= root.point[cd]) {
            rangeSearchRec(root.left, lower, upper,
                           depth + 1);
        }
        if (upper[cd] >= root.point[cd]) {
            rangeSearchRec(root.right, lower, upper,
                           depth + 1);
        }
    }

    // Method for range search
    void rangeSearch(int[] lower, int[] upper)
    {
        rangeSearchRec(root, lower, upper, 0);
    }

    public static void main(String[] args)
    {
        KDTree tree = new KDTree();

        int[][] points
            = { { 3, 6 }, { 17, 15 }, { 13, 15 }, { 6, 12 },
                { 9, 1 }, { 2, 7 },   { 10, 19 } };

        // Insert points into the K-D Tree
        for (int[] point : points) {
            tree.insert(point);
        }

        // Search for specific points in the K-D Tree
        System.out.println(
            tree.search(new int[] { 10, 19 })); // true
        System.out.println(
            tree.search(new int[] { 12, 19 })); // false

        // Range search for points within the specified
        // range
        int[] lower = { 0, 0 };
        int[] upper = { 10, 10 };

        // Print points within range
        tree.rangeSearch(lower, upper);
    }
}

Output
true
false
[3, 6]
[2, 7]
[9, 1]

Complexity Table:

Operation

Average Time Complexity

Worst Time Complexity

Space Complexity

Insertion

O(log N)

O(N)

O(N)

Search

O(log N)

O(N)

O(1)

Range Search

O(sqrt(N) + k)

O(N)

O(1)

Nearest Neighbor

O(log N)

O(N)

O(1)

Applications

  • Nearest Neighbor Search: Finding similar items (e.g., recommendations).
  • Database Indexing: Efficiently searching for data based on multiple attributes.
  • Collision Detection: In computer graphics and simulations.
  • Data Compression: Vector quantization techniques.



Reffered: https://www.geeksforgeeks.org


Java

Related
Java Program to Implement Fibonacci Heap Java Program to Implement Fibonacci Heap
Huffman Coding Java Huffman Coding Java
Balanced Binary Tree in Java Balanced Binary Tree in Java
Adding JGit to the Project with Maven Adding JGit to the Project with Maven
What is the difference between ArrayList.clear() and ArrayList.removeAll()? What is the difference between ArrayList.clear() and ArrayList.removeAll()?

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
14