【发布时间】:2014-02-16 08:50:56
【问题描述】:
因此,我的任务是构建具有 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;
}
}
这是我的代码的可视化。点号是插入的顺序。 如您所见,点 1 是根,(首先插入),点 2 向左移动,因为它的 x 坐标较小,点 3 向右等。
然后我们到达点 4、5、6 和 7。点 4 是垂直的,因为它的深度是均匀的,点 5 也应该是垂直的。它的x点小于点1,所以它向左,它的x点大于点2,所以它向右,成为点3s的右孩子,应该使它的深度均匀,从而垂直。右子树也有同样的问题。
非常欢迎任何额外的解释。
【问题讨论】:
标签: java data-structures kdtree recursive-datastructures