详解Kd树之查找

kd树已经构造好,如何查找kd树,接着上篇博文

void searchPathFinding(double []target,SNode kd_point){
//TODO 发现路径
Stack> pathStack = new Stack>();
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> pathStack){
//对路径上的点进行回溯筛选
SNode nearest = pathStack.pop();
double max_dist = countDistance(nearest.data, target);
while(!pathStack.end()){
SNode 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;
}
d
ouble countDistance(int[] point,double[] target){
return Math.sqrt(Math.pow((point[0] - target[0]),2)+Math.pow((point[1]-target[1]),2));
}

查找的过程如度娘所描述的

  1. 从root节点开始,DFS搜索直到叶子节点,同时在stack中顺序存储已经访问的节点。
  2. 如果搜索到叶子节点,当前的叶子节点被设为最近邻节点。
  3. 然后通过stack回溯:
    如果当前点的距离比最近邻点距离近,更新最近邻节点.
    然后检查以最近距离为半径的圆是否和父节点的超平面相交.
    如果相交,则必须到父节点的另外一侧,用同样的DFS搜索法,开始检查最近邻节点。
    如果不相交,则继续往上回溯,而父节点的另一侧子节点都被淘汰,不再考虑的范围中.
  4. 当搜索回到root节点时,搜索完成,得到最近邻节点。
详解Kd树之查找_第1张图片

详解Kd树之查找_第2张图片
博文参考:
http://www.dataguru.cn/article-4722-1.html

http://wenku.baidu.com/link?url=biVgsUniKgAI2ZIXtSEfz60EIhnXAvMJFBERtbaNSvt9Se8KixwLghPIqQG3cifg767I_ONRSrdOnLWW9KX3C0KpaPWHt5R1PiDMslmnAzG

http://baike.baidu.com/link?url=kTUf8ZEeC2wJa-aNO4ktmpsefgaUdsMaAxO0fK1LBQHXTXzKniGaKHpWB4Hj1dlReB4aw4AakRsqoRPTHb9gKq

你可能感兴趣的:(算法,java)