作业地址:http://coursera.cs.princeton.edu/algs4/assignments/kdtree.html
作业难点:
1、如何构建KdTree,使用什么样的数据结构?
根据作业提示:
private static class KdNode {
private Point2D point;
private boolean direction;
private RectHV rect;
private KdNode lb, rt;
KdNode(Point2D p, boolean drct) {
if (p == null)
throw new NullPointerException();
direction = drct;
point = p;
rect = null;
lb = null;
rt = null;
}
}
2、draw()怎么实现感觉不会觉得很别扭?
建一个迭代器可以遍历整个KdTee,这里使用前序遍历。
private Iterable<KdNode> kdnodes()
{
Queue<KdNode> kNodes = new Queue<KdNode>();
preorder(kdt, kNodes);
return kNodes;
}
private void preorder(KdNode root, Queue<KdNode> q) {
if (root == null) return;
q.enqueue(root);
preorder(root.lb, q);
preorder(root.rt, q);
}
3、如何回溯最优解,是否需要parent指针?
递归深入,无需parent指针。
容易扣分点:
1、insert()重复建Rect;
2、nearest()空指针溢出。
部分代码参考:
nearest():
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public Point2D nearest(Point2D p) { if (p == null) throw new NullPointerException(); if (kdt != null) return nearPoint(kdt, p, kdt).point; return null; } private KdNode nearPoint(KdNode kd, Point2D p, KdNode q) { if (kd == null) return q; double nrDist = p.distanceSquaredTo(q.point); double kdDist = p.distanceSquaredTo(kd.point); if (nrDist >= kdDist || nrDist >= kd.rect.distanceSquaredTo(p)) { if (nrDist > kdDist) q = kd; if (kd.direction) { double cmpX = p.x() - kd.point.x(); if (cmpX < 0.0) { if (kd.lb != null) q = nearPoint(kd.lb, p, q); if (kd.rt != null) q = nearPoint(kd.rt, p, q); } else { if (kd.rt != null) q = nearPoint(kd.rt, p, q); if (kd.lb != null) q = nearPoint(kd.lb, p, q); } } else { double cmpY = p.y() - kd.point.y(); if (cmpY < 0.0) { if (kd.lb != null) q = nearPoint(kd.lb, p, q); if (kd.rt != null) q = nearPoint(kd.rt, p, q); } else { if (kd.rt != null) q = nearPoint(kd.rt, p, q); if (kd.lb != null) q = nearPoint(kd.lb, p, q); } } } return q; }