Java 创建一个插入和可视化逻辑的KDTree

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.*

所以我的任务是构建一个节点类型为Point2D的KdTree。首先从insert方法开始,确保节点按x轴相应放置,然后构造与之协调工作的draw()方法

我已经这样做了,并且完成了一些其他的方法,虽然我还没有从试图找出前两种方法中拔出我的头发,但这是我的问题

从视觉和性能上看,我的结构在每次测试中都能正常工作,但我仍然认为这是不对的

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的右边,它接受那个分支