|
1 | 1 | import java.util.ArrayList; |
| 2 | + |
2 | 3 | import edu.princeton.cs.algs4.Point2D; |
3 | 4 | import edu.princeton.cs.algs4.RectHV; |
4 | 5 |
|
@@ -172,40 +173,48 @@ private void rangeSearch(RectHV rect, Node node, ArrayList<Point2D> points) { |
172 | 173 | } |
173 | 174 | } |
174 | 175 | } |
175 | | - // // a nearest neighbor in the set to point p; null if the set is empty |
| 176 | + |
| 177 | + // a nearest neighbor in the set to point p; null if the set is empty |
176 | 178 | public Point2D nearest(Point2D p) { |
177 | 179 | if (p == null) throw new IllegalArgumentException("nearest method called with a null argument"); |
178 | | - return nearestSearch(p, this.root, null, Double.POSITIVE_INFINITY); |
| 180 | + return nearestSearch(this.root, p, null, Double.POSITIVE_INFINITY); |
179 | 181 | } |
180 | 182 |
|
181 | | - private Point2D nearestSearch(Point2D p, Node node, Point2D nearest, double minDistance) { |
182 | | - if (node == null) return nearest; |
| 183 | + private Point2D nearestSearch(Node node, Point2D target, Point2D nearestPoint, double nearestDistance) { |
| 184 | + if (node == null) return null; |
183 | 185 |
|
184 | | - double distance = p.distanceSquaredTo(node.point); |
185 | | - if (distance < minDistance) { |
186 | | - nearest = node.point; |
187 | | - minDistance = distance; |
| 186 | + double distance = node.point.distanceSquaredTo(target); |
| 187 | + if (distance < nearestDistance) { |
| 188 | + nearestPoint = node.point; |
| 189 | + nearestDistance = distance; |
188 | 190 | } |
189 | 191 |
|
| 192 | + Node first, second; |
190 | 193 | if (node.isVertical) { |
191 | | - if (p.x() < node.point.x()) { |
192 | | - nearest = nearestSearch(p, node.left, nearest, minDistance); |
193 | | - nearest = nearestSearch(p, node.right, nearest, nearest.distanceSquaredTo(p)); |
| 194 | + if (target.x() < node.point.x()) { |
| 195 | + first = node.left; |
| 196 | + second = node.right; |
194 | 197 | } else { |
195 | | - nearest = nearestSearch(p, node.right, nearest, minDistance); |
196 | | - nearest = nearestSearch(p, node.left, nearest, nearest.distanceSquaredTo(p)); |
| 198 | + first = node.right; |
| 199 | + second = node.left; |
197 | 200 | } |
198 | 201 | } else { |
199 | | - if (p.y() < node.point.y()) { |
200 | | - nearest = nearestSearch(p, node.left, nearest, minDistance); |
201 | | - nearest = nearestSearch(p, node.right, nearest, nearest.distanceSquaredTo(p)); |
| 202 | + if (target.y() < node.point.y()) { |
| 203 | + first = node.left; |
| 204 | + second = node.right; |
202 | 205 | } else { |
203 | | - nearest = nearestSearch(p, node.right, nearest, minDistance); |
204 | | - nearest = nearestSearch(p, node.left, nearest, nearest.distanceSquaredTo(p)); |
| 206 | + first = node.right; |
| 207 | + second = node.left; |
205 | 208 | } |
206 | 209 | } |
207 | 210 |
|
208 | | - return nearest; |
| 211 | + nearestPoint = nearestSearch(first, target, nearestPoint, nearestDistance); |
| 212 | + |
| 213 | + if (second != null && second.point.distanceSquaredTo(target) < nearestDistance) { |
| 214 | + nearestPoint = nearestSearch(second, target, nearestPoint, nearestDistance); |
| 215 | + } |
| 216 | + |
| 217 | + return nearestPoint; |
209 | 218 | } |
210 | 219 |
|
211 | 220 | // unit testing of the methods (optional) |
|
0 commit comments