Java 创建一个插入和可视化逻辑的KDTree
所以我的任务是构建一个节点类型为Point2D的KdTree。首先从insert方法开始,确保节点按x轴相应放置,然后构造与之协调工作的draw()方法 我已经这样做了,并且完成了一些其他的方法,虽然我还没有从试图找出前两种方法中拔出我的头发,但这是我的问题 从视觉和性能上看,我的结构在每次测试中都能正常工作,但我仍然认为这是不对的Java 创建一个插入和可视化逻辑的KDTree,java,data-structures,kdtree,recursive-datastructures,Java,Data Structures,Kdtree,Recursive Datastructures,所以我的任务是构建一个节点类型为Point2D的KdTree。首先从insert方法开始,确保节点按x轴相应放置,然后构造与之协调工作的draw()方法 我已经这样做了,并且完成了一些其他的方法,虽然我还没有从试图找出前两种方法中拔出我的头发,但这是我的问题 从视觉和性能上看,我的结构在每次测试中都能正常工作,但我仍然认为这是不对的 package algs32.kdtree; import algs12.Point2D; import algs13.Queue; import stdlib.*
package algs32.kdtree;
import algs12.Point2D;
import algs13.Queue;
import stdlib.*;
public class KdTree {
private static class KNode {
private KNode left, right;
private boolean vertical;
private Point2D key;
public KNode(final Point2D key, final boolean v) {
this.key = key;
vertical = v;
}
}
private static final RectHV BOUNDRY = new RectHV(0, 0, 1, 1);
private KNode root;
private int size;
public KdTree() {}
public int size() { return size; }
public boolean isEmpty() { return size == 0; }
public void insert(Point2D p) { root = insert(root, p, true); }
private KNode insert(KNode node, final Point2D p, final boolean vertical) {
if (p == null) { throw new IllegalArgumentException(); }
if (node == null) {
size++;
node = new KNode(p, vertical);
return node;
}
if (p.equals(node.key)) { return node; }
if (node.vertical && p.x() < node.key.x() || !node.vertical && p.y() < node.key.y()) {
node.left = insert(node.left, p, !node.vertical);
}
else {
node.right = insert(node.right, p, !node.vertical);
}
return node;
}
public void draw() { draw (root, BOUNDRY); }
private void draw (KNode node, RectHV area) {
if (node==null) return;
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.setPenRadius(.007);
node.key.draw();
StdDraw.setPenRadius(.002);
if (node.vertical) {
StdDraw.setPenColor(StdDraw.RED);
StdDraw.line(node.key.x(), area.ymin(), node.key.x(), area.ymax());
} else {
StdDraw.setPenColor(StdDraw.BLUE);
StdDraw.line(area.xmin(), node.key.y(), area.xmax(), node.key.y());
}
draw(node.left, LR(area, node));
draw(node.right, RR(area, node));
}
private static RectHV LR(RectHV area, KNode node) {
if (node.vertical) {
RectHV newarea = new RectHV(area.xmin(), area.ymin(), node.key.x(), area.ymax());
return area;
} else {// BR for horizontal division
RectHV newarea = new RectHV(area.xmin(), area.ymin(), area.xmax(), node.key.y());
return area;
}
}
private static RectHV RR(RectHV area, KNode node) {
if (node.vertical) {
RectHV newarea = new RectHV(node.key.x(), area.ymin(), area.xmax(), area.ymax());
return newarea;
} else {// TR for horizontal division
RectHV newarea = new RectHV(area.xmin(), node.key.y(), area.xmax(), area.ymax());
return area;
}
}
包algs32.kdtree;
导入algs12.Point2D;
导入algs13.队列;
进口stdlib.*;
公共类KdTree{
私有静态类KNode{
私人诺德左,右;
私有布尔垂直;
私钥;
公共旋钮(最终点2D键,最终布尔值v){
this.key=key;
垂直=v;
}
}
私有静态最终RectHV边界=新的RectHV(0,0,1,1);
独活根;
私有整数大小;
公共KdTree(){}
public int size(){return size;}
公共布尔值isEmpty(){return size==0;}
公共void insert(point2dp){root=insert(root,p,true);}
专用旋钮插入(旋钮节点,最终点2D p,最终布尔垂直){
如果(p==null){抛出新的IllegalArgumentException();}
if(node==null){
大小++;
节点=新旋钮(p,垂直);
返回节点;
}
如果(p.equals(node.key)){return node;}
if(node.vertical&&p.x()
这是我代码的可视化。点号是插入的顺序。
如您所见,点1是根(首先插入),点2向左,因为它具有较小的x坐标,点3向右等等
然后我们到达点4,5,6和7。点4是垂直的,因为它的深度是均匀的,点5也应该是垂直的。它的x点比点1小,所以它向左移动,它的x点比点2大,所以它向右移动,成为点3的右子对象,这应该使它的深度均匀,因此是垂直的。对于右子图来说,同样的问题e
任何额外的解释都是非常受欢迎的
然后我们到达点4、5、6和7。点4是垂直的,因为它是垂直的
深度是均匀的,第5点也应该是。它的x点小于
点1,它向左移动,它的x点比点2大,
所以它向右转,成为point 3s的正确孩子,应该
使其深度均匀,从而垂直。右侧也有同样的问题
子树
这是不正确的。一旦你沿着树的一个分支往下走,你就呆在那里。因此点1在根上,有子2和3。2有子4,4有子5。因此5应该是水平的,因为它是4的子,是2的子,是1的子。
维基百科对kd树有很好的解释:
总之,因为点5在1的左边,它进入那个分支。因为它在2以下,它接受那个分支。因为它在4的右边,它接受那个分支