Algorithms assignment5和recursive

这一次作业运用了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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值