首页 > 代码库 > 算法导论第四版学习——习题五Kd-Tree
算法导论第四版学习——习题五Kd-Tree
题目正文:
http://coursera.cs.princeton.edu/algs4/assignments/kdtree.html
作业难点:
如何组织自己的数据结构是本道题的最难点,基本上有思路就肯定可以完成。题目一定要看仔细,基本上2dtree部分已经把实现原理说清楚了。
作业技巧:
1、逐步实现,实现完成后用insert、contain测试下,没问题再写draw,测试没问题再写其余的。
2、重复输入的问题不要忘了
3、range虽然api里写的是all point inside the rectangle,但是你必须把边界上的点也算进去
4、java不像C#可以传参数前面加ref或out,所以必须在递归的时候返回Point
5、比较容易疏忽的是子节点在分界线上部或者下部的处理是不一样的,你认为左边是右子树,上边是左子树都没关系。最后结果不会有问题
代码参考:
(这是我自己亲测100分的答案,不代表写得最好,请在自己实在完成不了的时候再看,不然的话做这个题目的意义一点都没有)
1 import edu.princeton.cs.algs4.Point2D; 2 import edu.princeton.cs.algs4.RectHV; 3 import edu.princeton.cs.algs4.SET; 4 5 import java.util.Stack; 6 7 8 public class PointSET { 9 private SET<Point2D> pointSet;10 11 public PointSET() // construct an empty set of points 12 {13 pointSet = new SET<Point2D>();14 }15 16 private void checkNull(Object obj) {17 if (obj == null) {18 throw new NullPointerException();19 }20 }21 22 public boolean isEmpty() // is the set empty? 23 {24 return pointSet.isEmpty();25 }26 27 public int size() // number of points in the set 28 {29 return pointSet.size();30 }31 32 public void insert(Point2D p) // add the point to the set (if it is not already in the set)33 {34 checkNull(p);35 pointSet.add(p);36 }37 38 public boolean contains(Point2D p) // does the set contain point p? 39 {40 checkNull(p);41 42 return pointSet.contains(p);43 }44 45 public void draw() // draw all points to standard draw 46 {47 for (Point2D p : pointSet) {48 p.draw();49 }50 }51 52 public Iterable<Point2D> range(RectHV rect) // all points that are inside the rectangle 53 {54 checkNull(rect);55 56 Stack<Point2D> stack = new Stack<Point2D>();57 58 for (Point2D p : pointSet) {59 if ((p.x() >= rect.xmin()) && (p.x() <= rect.xmax()) &&60 (p.y() >= rect.ymin()) && (p.y() <= rect.ymax())) {61 stack.push(p);62 }63 }64 65 return stack;66 }67 68 public Point2D nearest(Point2D p) // a nearest neighbor in the set to point p; null if the set is empty 69 {70 checkNull(p);71 72 Point2D point = null;73 74 for (Point2D setp : pointSet) {75 if ((point == null) ||76 (p.distanceSquaredTo(point) > p.distanceSquaredTo(setp))) {77 point = setp;78 }79 }80 81 return point;82 }83 84 public static void main(String[] args) // unit testing of the methods (optional) 85 {86 }87 }
1 import edu.princeton.cs.algs4.In; 2 import edu.princeton.cs.algs4.Point2D; 3 import edu.princeton.cs.algs4.RectHV; 4 import edu.princeton.cs.algs4.StdDraw; 5 import edu.princeton.cs.algs4.StdOut; 6 7 import java.util.Stack; 8 9 10 public class KdTree { 11 private PointNode root; 12 private int pointCount; 13 14 public KdTree() // construct an empty set of points 15 { 16 root = null; 17 pointCount = 0; 18 } 19 20 private void checkNull(Object obj) { 21 if (obj == null) { 22 throw new NullPointerException(); 23 } 24 } 25 26 public boolean isEmpty() // is the set empty? 27 { 28 return root == null; 29 } 30 31 public int size() // number of points in the set 32 { 33 return pointCount; 34 } 35 36 public void insert(Point2D p) // add the point to the set (if it is not already in the set) 37 { 38 checkNull(p); 39 40 if (root == null) { 41 root = new PointNode(p, null, false); 42 pointCount++; 43 } else { 44 PointNode current = root; 45 46 while (true) { 47 if (current.value.compareTo(p) == 0) { 48 return; 49 } 50 if (current.isAtLeftSideOfNode(p)) { 51 if (current.left == null) { 52 current.left = new PointNode(p, current, true); 53 pointCount++; 54 break; 55 } else { 56 current = current.left; 57 } 58 } else { 59 if (current.right == null) { 60 current.right = new PointNode(p, current, false); 61 pointCount++; 62 break; 63 } else { 64 current = current.right; 65 } 66 } 67 } 68 } 69 } 70 71 public boolean contains(Point2D p) // does the set contain point p? 72 { 73 checkNull(p); 74 75 PointNode current = root; 76 77 while (current != null) { 78 if (current.value.compareTo(p) == 0) { 79 return true; 80 } else if (current.isAtLeftSideOfNode(p)) { 81 current = current.left; 82 } else { 83 current = current.right; 84 } 85 } 86 87 return false; 88 } 89 90 public void draw() // draw all points to standard draw 91 { 92 if (root != null) { 93 root.draw(null, false); 94 } 95 } 96 97 private void addToStack(Stack<Point2D> stack, PointNode current, RectHV rect) { 98 99 if (!rect.intersects(current.rect)) {100 return;101 }102 103 if ((current.value.x() >= rect.xmin()) &&104 (current.value.x() <= rect.xmax()) &&105 (current.value.y() >= rect.ymin()) &&106 (current.value.y() <= rect.ymax())) {107 stack.push(current.value);108 }109 110 if (current.left != null) {111 addToStack(stack, current.left, rect);112 }113 114 if (current.right != null) {115 addToStack(stack, current.right, rect);116 }117 }118 119 private Point2D searchNode(Point2D toSearch, PointNode current,120 Point2D nearestPoint) {121 if (nearestPoint == null) {122 nearestPoint = current.value;123 }124 125 double distance = nearestPoint.distanceSquaredTo(toSearch);126 double newdistance = current.value.distanceSquaredTo(toSearch);127 128 if ((distance >= current.rect.distanceSquaredTo(toSearch)) ||129 (distance >= newdistance)) {130 if (distance > newdistance) {131 nearestPoint = current.value;132 }133 134 if ((current.isH && (toSearch.y() > current.value.y())) ||135 (!current.isH && (toSearch.x() < current.value.x()))) {136 if (current.left != null) {137 nearestPoint = searchNode(toSearch, current.left,138 nearestPoint);139 }140 141 if (current.right != null) {142 nearestPoint = searchNode(toSearch, current.right,143 nearestPoint);144 }145 } else {146 if (current.right != null) {147 nearestPoint = searchNode(toSearch, current.right,148 nearestPoint);149 }150 151 if (current.left != null) {152 nearestPoint = searchNode(toSearch, current.left,153 nearestPoint);154 }155 }156 }157 158 return nearestPoint;159 }160 161 public Iterable<Point2D> range(RectHV rect) // all points that are inside the rectangle 162 {163 checkNull(rect);164 165 Stack<Point2D> stack = new Stack<Point2D>();166 if (root != null)167 addToStack(stack, root, rect);168 169 return stack;170 }171 172 public Point2D nearest(Point2D p) // a nearest neighbor in the set to point p; null if the set is empty 173 {174 checkNull(p);175 176 Point2D point = null;177 if (root != null)178 point = searchNode(p, root, point);179 180 return point;181 }182 183 public static void main(String[] args) // unit testing of the methods (optional) 184 {185 String filename = args[0];186 In in = new In(filename);187 188 KdTree kdtree = new KdTree();189 190 while (!in.isEmpty()) {191 double x = in.readDouble();192 double y = in.readDouble();193 Point2D p = new Point2D(x, y);194 kdtree.insert(p);195 }196 197 kdtree.draw();198 }199 200 private static class PointNode {201 private PointNode left;202 private PointNode right;203 private RectHV rect;204 private Point2D value;205 private boolean isH;206 207 public PointNode(Point2D p, PointNode parent, boolean isLeftUp) {208 value =http://www.mamicode.com/ p;209 left = null;210 right = null;211 if (parent == null) {212 isH = false;213 rect = new RectHV(0, 0, 1, 1);214 } else {215 isH = !parent.isH;216 217 if (isH) {218 if (isLeftUp) {219 rect = new RectHV(parent.rect.xmin(),220 parent.rect.ymin(), parent.value.x(),221 parent.rect.ymax());222 } else {223 rect = new RectHV(parent.value.x(), parent.rect.ymin(),224 parent.rect.xmax(), parent.rect.ymax());225 }226 } else {227 if (isLeftUp) {228 rect = new RectHV(parent.rect.xmin(), parent.value.y(),229 parent.rect.xmax(), parent.rect.ymax());230 } else {231 rect = new RectHV(parent.rect.xmin(),232 parent.rect.ymin(), parent.rect.xmax(),233 parent.value.y());234 }235 }236 }237 }238 239 public void draw(PointNode parent, boolean isLeftUp) {240 StdOut.println(isLeftUp ? "leftup" : "rightdown");241 StdDraw.setPenColor(StdDraw.BLACK);242 StdDraw.setPenRadius(0.01);243 value.draw();244 StdDraw.setPenRadius();245 246 if (parent == null) {247 StdDraw.setPenColor(StdDraw.RED);248 new Point2D(value.x(), 1).drawTo(new Point2D(value.x(), 0));249 } else {250 StdOut.println(value);251 StdOut.println(parent.rect);252 253 if (parent.isH) {254 StdDraw.setPenColor(StdDraw.RED);255 new Point2D(value.x(), rect.ymin()).drawTo(new Point2D(256 value.x(), rect.ymax()));257 } else {258 StdDraw.setPenColor(StdDraw.BLUE);259 new Point2D(rect.xmax(), value.y()).drawTo(new Point2D(260 rect.xmin(), value.y()));261 }262 }263 264 StdDraw.pause(100);265 266 if (left != null) {267 left.draw(this, true);268 }269 270 if (right != null) {271 right.draw(this, false);272 }273 }274 275 public boolean isAtLeftSideOfNode(Point2D p) {276 if (isH) {277 return p.y() > value.y();278 } else {279 return p.x() < value.x();280 }281 }282 }283 }
算法导论第四版学习——习题五Kd-Tree
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。