Spatial Data Structures
K-D Trees, PR Quadtrees
Multi-dimensional queries
Range queries
Applications
K-D Trees: a Generalization of BSTs
Binary Search Trees search using 1 key
Some data naturally contain multiple dimensions
Given k-dimensional data, a K-D tree indexes dimension 0 of the data at level 0, dimension 1 at level 1, etc.
Figure 13.8 (b) from book
Definition: the discriminator is the search key at each level i
calculation of discriminator : i mod k
Given 3-dimensional data indexed by (x,y,z),
y is the discriminator if the level number of the k-d tree is 10 since 10 mod 3 = 1
K-D Trees .
At ith level of the tree, discriminator indexes the tree exactly as for a BST: select i mod kth coordinate of data item and compare it with i mod kth coordinate of value stored at node of K-D tree.
If (data value < node value) take-left-branch
else take-right-branch // >= case
For 2-D space, K-D tree subdivides space into rectangles. The direction of subdivision alternates among the dimensions:
Figure 13.8 (a) from book
K-D Tree Find Operation
Simple modification of BST search.
Must determine correct discriminator at each level (= level number mod k) to find out what coordinate of key to use for comparison at that level
KDNode* KD::Kdfindhelp(KDNode* rt, ELEM val, int lev, int K) const {
//lev: current level (mod K); K: number of dimensions
//dkey(val, i) returns the key value of val for dimension i
if (rt == NULL) return NULL; // Empty tree
else if (val == rt->value) return rt; // Found it
else if (dkey(val, lev) < dkey(rt->value, lev))
return Kdfindhelp(rt->left, val, (lev+1) % K, K);
else
return Kdfindhelp(rt->right, val, (lev+1) % K, K);
}
Example: find (55, 80) in
Figure 13.8 (b) from book
Deleting Nodes in a K-D Tree
Deletion similar to BST but slightly harder.
Step 1: find node to be deleted
Step 2: two cases must be handled
No children - replace ptr to node by NULL
Has children - replace node by minimum node in right subtree using
If no right subtree exists, then first move left subtree to become right subtree and proceed with usual delete procedure using
KDfindminSpecial note: node found by
KDfindmin may occur in middle of tree. Recursive call to the delete routine must be used to replace it (careful!)KDfindmin
Must search both left and right subtrees to find minimum value for a given discriminator
KDNode* KD::KDfindmin(KDNode* rt, int discrim,
int level, int K) {
// discrim: discriminator key used for minimum search
// level: current level(mod K); K: # of levels in key
KDNode *temp1, *temp2;
if (rt == NULL) return NULL;
temp1 = KDfindmin(rt->left, discrim, (level+1)%K, K)
if (discrim != level) { //Min val could be on l/r side
temp2=KDfindmin(rt->right, discrim, (level+1)%K,K);
if((temp1 == NULL) || ((temp2 != NULL) &&
(dkey(temp2->value,discrim) <
dkey(temp1->value,discrim)))) temp1 = temp2;
//in line above, rt subtree has smaller key value
}
// temp1 has the smallest value in children (if any)
if ((temp1 == NULL) ||
(dkey(rt->value,discrim) <
dkey(temp1->value,discrim))) return rt;
else return temp1;
}
Now delete C(70, 10) from
Figure 13.8 (b) from book
K-D Tree Range Query
Problem: find all k-dimensional points within distance 'D' of point P
Must search through K-D tree using Euclidean distance formula
If any coordinate in the K-D tree is more than distance 'D' away from point P's corresponding coordinate, then no need to search one of the subtrees below that node.
Example: if D=10, y-coordinate of node is being examined and is 13 less than the y-coordinate of P, then no search needed of left subtree below that node
void KDRegionSearch(KDNode* rt, ELEM val, int D, int level, int K) {
// val: search key; D: search radius;
// level: current level (mod K); K: # of dimensions
// Check if record at rt is in circle
if(InCircle(key(val), D, key(rt->value)))
printout(rt->value);//Do appropriate action with node
if(dkey(rt->value,level)>(dkey(val,level)-D)//Go left
KDRegionSearch(rt->left, val, D, (level+1)%K,K);
if(dkey(rt->value,level)<(dkey(val,level)+D))//Go right
KDRegionSearch(rt->right, val, D, (level+1) % K, K); }
Function 'InCircle' uses Euclidean distance to test if point is within distance D of query point