所以我的任务是编写一个具有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;
}
}
这是我的代码的可视化。点数是插入的顺序。 如您所见,Point 1是根,(先插入),Point 2向左移动,因为它有一个较小的x坐标,Point 3在右边等。
然后我们到达第4,5,6和4点。 7.第4点是垂直的,因为它的深度是均匀的,第5点也是如此。它的x点小于点1,因此它向左移动,其x点大于点2,因此它向右移动,成为点3s'右子,它应该使其深度均匀,因此是垂直的。正确的子树也存在同样的问题。
非常欢迎任何额外的解释。
答案 0 :(得分:0)
然后我们到达第4,5,6和4点。 7.第4点是垂直的,因为它 深度是均匀的,第5点也应该是。它的x点小于 点1,所以它向左移动,其x点大于点2, 所以它走向正确,成为第3点'正确的孩子,应该 使其深度均匀,垂直。同样的问题是对的 子树。
这是不正确的。一旦你走到树的一个分支,你就呆在那里。因此,第1点位于根,并且有2个孩子和3个.2个孩子4个,4个孩子5个。因此5个应该是水平的,因为它是4的孩子,这是2的孩子,这是孩子1。 维基百科在这里对kd-trees有一个很好的解释:http://en.wikipedia.org/wiki/K-d_tree
总之,由于第5点位于1的左侧,因此它进入该分支。由于它低于2,它需要该分支。因为它在4的右边,所以需要那个分支。