作业地址: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():
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; }