// Source code example for "A Practical Introduction // to Data Structures and Algorithm Analysis" // by Clifford A. Shaffer, Prentice Hall, 1998. // Copyright 1998 by Clifford A. Shaffer public class KDtree { // k-d tree implementation private BinNode root; private int D; public KDtree(int dimension) { root = null; D = dimension; } public void clear() { root = null; } public void insert(DElem val) { root = inserthelp(root, val, 0); } public void remove(int[] key) { root = removehelp(root, key, 0); } public DElem find(int key[]) { return findhelp(root, key, 0); } public void regionSearch(int[] point, int radius) { rshelp(root, point, radius, 0); } public boolean isEmpty() { return root == null; } public void print() { // Print out the contents of the tree if (root == null) System.out.println("The k-d tree is empty."); else { printhelp(root, 0); System.out.println(); } } private BinNode inserthelp(BinNode rt, DElem val, int level) { if (rt == null) return new BinNodePtr(val); DElem it = (DElem) rt.element(); if (it.key(level) > val.key(level)) rt.setLeft(inserthelp(rt.left(), val, (level+1)%D)); else rt.setRight(inserthelp(rt.right(), val, (level+1)%D)); return rt; } private DElem findhelp(BinNode rt, int[] key, int level) { if (rt == null) return null; DElem it = (DElem)rt.element(); if (it.equalKey(key)) return (DElem)rt.element(); if (it.key(level) > key[level]) return findhelp(rt.left(), key, (level+1)%D); else return findhelp(rt.right(), key, (level+1)%D); } private DElem findmin(BinNode rt, int descrim, int level) { DElem temp1, temp2; if (rt == null) return null; temp1 = findmin(rt.left(), descrim, (level+1)%D); if (descrim != level) { temp2 = findmin(rt.right(), descrim, (level+1)%D); if ((temp1 == null) || ((temp2 != null) && (temp1.key(descrim) > temp2.key(descrim)))) temp1 = temp2; } // Now, temp1 has the smaller value if ((temp1 == null) || (temp1.key(descrim) > ((DElem)rt.element()).key(descrim))) return (DElem) rt.element(); else return temp1; } private void rshelp(BinNode rt, int[] point, int radius, int lev) { if (rt == null) return; if (InCircle(point, radius, ((DElem)rt.element()).coord())) System.out.println(rt.element()); if (((DElem)rt.element()).key(lev) > (point[lev] - radius)) rshelp(rt.left(), point, radius, (lev+1)%D); if (((DElem)rt.element()).key(lev) < (point[lev] + radius)) rshelp(rt.right(), point, radius, (lev+1)%D); } private void printhelp(BinNode rt, int level) { for(int i=1; i<=level; i++) System.out.print(" "); if (rt == null) System.out.println("null"); else System.out.println((DElem)rt.element()); if (rt == null) return; printhelp(rt.left(), level+1); printhelp(rt.right(), level+1); } private BinNode removehelp(BinNode rt, int[] key, int level) { if (rt == null) return null; DElem it = (DElem) rt.element(); if (key[level] < it.key(level)) rt.setLeft(removehelp(rt.left(), key, (level+1)%D)); else if (key[level] > it.key(level)) rt.setRight(removehelp(rt.right(), key, (level+1)%D)); else { // Found it if (rt.right() == null) if (rt.left() == null) // Just drop element return null; else { // Switch subtree to right rt.setRight(rt.left()); rt.setLeft(null); } DElem temp = findmin(rt.right(), level, (level+1)%D); rt.setRight(removehelp(rt.right(), temp.coord(), (level+1)%D)); rt.setElement(temp); } return rt; } private boolean InCircle(int[] point, int radius, int[] coord) { Assert.notFalse(point.length == coord.length, "Bad InCircle"); System.out.println("Test against " + coord[0] + ", " + coord[1]); int sum = 0; for (int i=0; i