kd树已经构造好,如何查找kd树,接着上篇博文
void searchPathFinding(double []target,SNode<int []> kd_point){
//TODO 发现路径
Stack<SNode<int []>> pathStack = new Stack<SNode<int []>>();
while(kd_point!=null){
pathStack.push(kd_point);
System.out.println(kd_point.data[0]+" "+kd_point.data[1]);
int split = kd_point.split;
if(target[split] <= kd_point.data[split]){
kd_point = kd_point.lc;
}else{
kd_point = kd_point.rc;
}
}
while(!pathStack.end()){
findSimilarPoint(target, pathStack) ;
}
}
int[] findSimilarPoint(double[] target,Stack<SNode<int []>> pathStack){
//对路径上的点进行回溯筛选
SNode<int []> nearest = pathStack.pop();
double max_dist = countDistance(nearest.data, target);
while(!pathStack.end()){
SNode<int []> back_point = pathStack.pop();
int split = back_point.split;
if(Math.abs(target[split] - back_point.data[split]) < max_dist){
if(target[split] <= back_point.data[split]){
back_point = back_point.rc;
}else{
back_point = back_point.lc;
}
}
if(countDistance(back_point.data, target) < max_dist){
nearest = back_point;
max_dist = countDistance(back_point.data, target);
}
}
System.out.println("nearest point is: "+ nearest.data[0]+" "+nearest.data[1] +" "+ max_dist);
return null;
}
double countDistance(int[] point,double[] target){
return Math.sqrt(Math.pow((point[0] - target[0]),2)+Math.pow((point[1]-target[1]),2));
}
查找的过程如度娘所描述的
-
从root节点开始,DFS搜索直到叶子节点,同时在stack中顺序存储已经访问的节点。
-
如果搜索到叶子节点,当前的叶子节点被设为最近邻节点。
-
然后通过stack回溯:如果当前点的距离比最近邻点距离近,更新最近邻节点.然后检查以最近距离为半径的圆是否和父节点的超平面相交.如果相交,则必须到父节点的另外一侧,用同样的DFS搜索法,开始检查最近邻节点。如果不相交,则继续往上回溯,而父节点的另一侧子节点都被淘汰,不再考虑的范围中.
-
当搜索回到root节点时,搜索完成,得到最近邻节点。
http://wenku.baidu.com/link?url=biVgsUniKgAI2ZIXtSEfz60EIhnXAvMJFBERtbaNSvt9Se8KixwLghPIqQG3cifg767I_ONRSrdOnLWW9KX3C0KpaPWHt5R1PiDMslmnAzG
http://baike.baidu.com/link?url=kTUf8ZEeC2wJa-aNO4ktmpsefgaUdsMaAxO0fK1LBQHXTXzKniGaKHpWB4Hj1dlReB4aw4AakRsqoRPTHb9gKq