您的位置:首页 > 编程语言 > Go语言

Algorithms assignment5和recursive

2014-03-07 23:42 302 查看
这一次作业运用了recursive来写。

public class KdTree {
private static class Node {
private Point2D point;      // the point
private RectHV rect;    // the axis-aligned rectangle corresponding to this node
private Node left;        // the left/bottom subtree
private Node right;        // the right/top subtree
private boolean vertical;
public Node(Point2D p,Node left,Node right,boolean v,RectHV rect){
this.point=p;
this.left=left;
this.right=right;
this.vertical=v;
this.rect=rect;
}
}

private Node root;
private int size;
public KdTree(){                               // construct an empty set of points
root=null;
size=0;
}
public boolean isEmpty(){                        // is the set empty?
return size()==0;
}
public int size(){                               // number of points in the set
return size;
}

public void insert(Point2D p){                   // add the point p to the set (if it is not already in the set)
root=insert(root,p,true,0,0,1,1);
}
private Node insert(Node node, Point2D p, boolean v, double xmin, double ymin, double xmax, double ymax){
// if new node, create it
if(node==null){
size++;
return new Node(p,null,null,v,new RectHV(xmin,ymin,xmax,ymax));
}
// if already in, return it
if (node.point.x() == p.x() && node.point.y() == p.y()) return node;

// else, insert it where corresponds (left - right recursive call)
if (node.vertical){                    //if node is in vertical level or odd level
if(p.x() < node.point.x()){
node.left = insert(node.left, p, !node.vertical, node.rect.xmin(),node.rect.ymin(),node.point.x(),node.rect.ymax());
}else{
node.right = insert(node.right, p, !node.vertical, node.point.x(),node.rect.ymin(),node.rect.xmax(),node.rect.ymax());
}
}else{								   //if node is in horizontal level or even level
if(p.y() < node.point.y()){
node.left = insert(node.left, p, !node.vertical, node.rect.xmin(),node.rect.ymin(),node.rect.xmax(),node.point.y());
}else{
node.right = insert(node.right, p, !node.vertical, node.rect.xmin(),node.point.y(),node.rect.xmax(),node.rect.ymax());
}
}
return node;
}
public boolean contains(Point2D p){              // does the set contain the point p?
return contains(root, p.x(),p.y());
}
private boolean contains(Node node, double x, double y)
{
if (node == null) return false;
if (node.point.x() == x && node.point.y() == y) return true;

if (node.vertical && x < node.point.x() || !node.vertical && y < node.point.y())
return contains(node.left, x, y);
else
return contains(node.right, x, y);
}
public void draw(){                              // draw all of the points to standard draw
draw(root);
}
private void draw(Node node){
if(node==null) return;
// draw the point
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.setPenRadius(0.01);
node.point.draw();

Point2D min, max;
if (node.vertical) {
StdDraw.setPenColor(StdDraw.RED);
min = new Point2D(node.point.x(), node.rect.ymin());
max = new Point2D(node.point.x(), node.rect.ymax());
} else {
StdDraw.setPenColor(StdDraw.BLUE);
min = new Point2D(node.rect.xmin(), node.point.y());
max = new Point2D(node.rect.xmax(), node.point.y());
}

// draw that division line
StdDraw.setPenRadius();
min.drawTo(max);

// recursively draw children
draw(node.left);
draw(node.right);
}
public Iterable<Point2D> range(RectHV rect){     // all points in the set that are inside the rectangle
Stack<Point2D> s = new Stack<Point2D>();
range(rect, root, s);
return s;
}
private void range(RectHV rect, Node node, Stack<Point2D> s){
if(node==null) return;
if(node.rect.intersects(rect)){
if(rect.contains(node.point)){
s.push(node.point);
}
range(rect,node.left,s);
range(rect,node.right,s);
}
}
public Point2D nearest(Point2D p){               // a nearest neighbor in the set to p; null if set is empty
return nearest(root,p,null);
}
private Point2D nearest(Node x, Point2D p, Point2D candidate) {
if (x == null) return candidate;      // if empty or the tree is searched over, return null or the presently nearest one

if(candidate==null){               // if x equals root, the nearest point is root
candidate=x.point;
}

double nearestD = candidate.distanceSquaredTo(p);

double distanceToPoint = x.point.distanceSquaredTo(p);

if(nearestD>x.rect.distanceSquaredTo(p)){         // judge whether this node and its subtree need to be processed
if(distanceToPoint<nearestD){
candidate=x.point;
}
if (x.left != null && x.right != null && x.left.rect.distanceSquaredTo(p) < x.right.rect.distanceSquaredTo(p)) {
candidate=nearest(x.left, p, candidate);
candidate=nearest(x.right, p, candidate);
}else{
candidate=nearest(x.right, p, candidate);
candidate=nearest(x.left, p, candidate);
}
}
return candidate;
}

}


有疑问可以看《Algorithms 4th Edition》399页的BST写法来加深理解,399页的get,由于方便,加上要递归,本来的get只有要get的参数,没有从哪里开始搜索,所以要加上root,所以分两个get写。

如果两个都是return value,那么直接return。如果像put这样,写的是void,那么就是root=put(root, key, val) 仔细看书上recursive的运用。这次的作业就是照着BST的写法写,也可以看github别人写的:https://gist.github.com/agjacome/5246693#file-kdtree-java-L85
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: