Example #1
0
 TreeNode* ClosestNode(TreeNode* root, double target) {
     if(target == root->val) {
         return root;
     }
     if(target < root->val) {
         if(root->left == NULL) {
             return root;
         }
         TreeNode* left = ClosestNode(root->left, target);
         if(abs(left->val - target) < abs(root->val - target)) {
             return left;
         }
         return root;
     }
     if(root->right == NULL) {
         return root;
     }
     TreeNode* right = ClosestNode(root->right, target);
     if(abs(right->val - target) < abs(root->val - target)) {
         return right;
     }
     return root;
 }
Example #2
0
 vector<int> closestKValues(TreeNode* root, double target, int k) {
     TreeNode* start = ClosestNode(root, target);
     vector<TreeNode*> left_stack;
     BuildStack(root, start, left_stack);
     vector<TreeNode*> right_stack(left_stack.begin(), left_stack.end());
     vector<int> result;
     result.push_back(start->val);
     TreeNode* larger_node = NULL;
     TreeNode* smaller_node = NULL;
     while(result.size() < k) {
         if(larger_node == NULL) {
             larger_node = LargerNode(right_stack);
         }
         if(smaller_node == NULL) {
             smaller_node = SmallerNode(left_stack);
         }
         if(larger_node == NULL) {
             result.push_back(smaller_node->val);
             smaller_node = NULL;
             continue;
         }
         if(smaller_node == NULL) {
             result.push_back(larger_node->val);
             larger_node = NULL;
             continue;
         }
         if(abs(smaller_node->val - target) < abs(larger_node->val - target)) {
             result.push_back(smaller_node->val);
             smaller_node = NULL;
         } else {
             result.push_back(larger_node->val);
             larger_node = NULL;
         }
     }
     return result;
 }
Example #3
0
BOOL CcdrawDoc::AddArcSegment(CComplex p0, CComplex p1, CArcSegment &asegm, double tol)
{
	int i,j,k;
	CSegment segm;
	CArcSegment newarc;
	CComplex c,p[2];
	CArray< CComplex, CComplex&> newnodes;
	double R,d,dmin,t;

	asegm.n0=ClosestNode(p0.re,p0.im);
	asegm.n1=ClosestNode(p1.re,p1.im);

	newnodes.RemoveAll();

	// don't add if line is degenerate
	if (asegm.n0==asegm.n1) return FALSE;

	// don't add if the arc is already in the list;
	for(i=0;i<arclist.GetSize();i++){
		if ((arclist[i].n0==asegm.n0) && (arclist[i].n1==asegm.n1) &&
			(fabs(arclist[i].ArcLength-asegm.ArcLength)<1.e-02)) return FALSE;
		// arcs are ``the same'' if start and end points are the same, and if
		// the arc lengths are relatively close (but a lot farther than
		// machine precision...
	}

	// add proposed arc to the linelist
	asegm.IsSelected=FALSE;
	
	// check to see if there are intersections
	for(i=0;i<linelist.GetSize();i++)
	{
		j=GetLineArcIntersection(linelist[i],asegm,p);
		if(j>0) for(k=0;k<j;k++) newnodes.Add(p[k]);
	}
	for(i=0;i<arclist.GetSize();i++)
	{
		j=GetArcArcIntersection(asegm,arclist[i],p);
		if(j>0) for(k=0;k<j;k++) newnodes.Add(p[k]);
	}

	// add nodes at intersections
	if (tol==0)
	{
		if (nodelist.GetSize()<2) t=1.e-08;
		else{
			CComplex p0,p1;
			p0=nodelist[0].CC();
			p1=p0;
			for(i=1;i<nodelist.GetSize();i++)
			{
				if(nodelist[i].x<p0.re) p0.re=nodelist[i].x;
				if(nodelist[i].x>p1.re) p1.re=nodelist[i].x;
				if(nodelist[i].y<p0.im) p0.im=nodelist[i].y;
				if(nodelist[i].y>p1.im) p1.im=nodelist[i].y;
			}
			t=abs(p1-p0)*CLOSE_ENOUGH;
		}
	}
	else t=tol;

	for(i=0;i<newnodes.GetSize();i++) 
		AddNode(newnodes[i].re,newnodes[i].im,t);

	// add proposed arc segment;
	arclist.Add(asegm);

	// check to see if proposed arc passes through other points;
    // if so, delete arc and create arcs that link intermediate points;
    // does this by recursive use of AddArcSegment;
	UnselectAll();
	GetCircle(asegm,c,R);
    if (tol==0) dmin=fabs(R*PI*asegm.ArcLength/180.)*1.e-05;
	else dmin=tol;
    k=(int) arclist.GetSize()-1;
			
    for(i=0;i<nodelist.GetSize();i++)
    {
        if( (i!=asegm.n0) && (i!=asegm.n1) )
        {
           	d=ShortestDistanceFromArc(CComplex(nodelist[i].x,nodelist[i].y), arclist[k]);
            if (d<dmin){
				CComplex a0,a1,a2;
				a0.Set(nodelist[asegm.n0].x,nodelist[asegm.n0].y);
				a1.Set(nodelist[asegm.n1].x,nodelist[asegm.n1].y);
				a2.Set(nodelist[i].x,nodelist[i].y);
                arclist[k].ToggleSelect();
                DeleteSelectedArcSegments();

				newarc=asegm;
				newarc.n1=i;
				newarc.ArcLength=arg((a2-c)/(a0-c))*180./PI;
                AddArcSegment(newarc,dmin);

				newarc=asegm;
				newarc.n0=i;
				newarc.ArcLength=arg((a1-c)/(a2-c))*180./PI;
                AddArcSegment(newarc,dmin);

                i=(int) nodelist.GetSize();
            }
        }
    }
   
	return TRUE;
}
Example #4
0
BOOL CcdrawDoc::AddSegment(CComplex p0, CComplex p1, CSegment &segm, double tol)
{
	int i,j,k,n0,n1;
	double xi,yi,t;
	CComplex p[2];
	CArray< CComplex, CComplex&> newnodes;

	newnodes.RemoveAll();

	n0=ClosestNode(p0.re,p0.im);
	n1=ClosestNode(p1.re,p1.im);

	// don't add if line is degenerate
	if (n0==n1) return FALSE;
	
	// don't add if the line is already in the list;
	for(i=0;i<linelist.GetSize();i++){
		if ((linelist[i].n0==n0) && (linelist[i].n1==n1)) return FALSE;
		if ((linelist[i].n0==n1) && (linelist[i].n1==n0)) return FALSE;
	}

	segm.IsSelected=FALSE; segm.n0=n0; segm.n1=n1; 
	
	// check to see if there are intersections with segments
	for(i=0;i<linelist.GetSize();i++)
		if(GetIntersection(n0,n1,i,&xi,&yi)==TRUE)  newnodes.Add(CComplex(xi,yi));

	// check to see if there are intersections with arcs
	for(i=0;i<arclist.GetSize();i++){
		j=GetLineArcIntersection(segm,arclist[i],p);
		if (j>0) for(k=0;k<j;k++) newnodes.Add(p[k]);
	}

	// add nodes at intersections
	if(tol==0)
	{
		if (nodelist.GetSize()<2) t=1.e-08;
		else{
			CComplex p0,p1;
			p0=nodelist[0].CC();
			p1=p0;
			for(i=1;i<nodelist.GetSize();i++)
			{
				if(nodelist[i].x<p0.re) p0.re=nodelist[i].x;
				if(nodelist[i].x>p1.re) p1.re=nodelist[i].x;
				if(nodelist[i].y<p0.im) p0.im=nodelist[i].y;
				if(nodelist[i].y>p1.im) p1.im=nodelist[i].y;
			}
			t=abs(p1-p0)*CLOSE_ENOUGH;
		}
	}
	else t=tol;

	for(i=0;i<newnodes.GetSize();i++) 
		AddNode(newnodes[i].re,newnodes[i].im,t);
	
	// Add proposed line segment
	linelist.Add(segm);

	// check to see if proposed line passes through other points;
    // if so, delete line and create lines that link intermediate points;
    // does this by recursive use of AddSegment;
	double d,dmin;
    UnselectAll();
    if (tol==0) dmin=abs(nodelist[n1].CC()-nodelist[n0].CC())*1.e-05;
	else dmin=tol;

    k=(int) linelist.GetSize()-1;
    for(i=0;i<nodelist.GetSize();i++)
    {
        if( (i!=n0) && (i!=n1) )
        {
            d=ShortestDistance(nodelist[i].x,nodelist[i].y,k);
			// catch a special case...
			if (abs(nodelist[i].CC()-nodelist[n0].CC())<dmin) d=2.*dmin;
			if (abs(nodelist[i].CC()-nodelist[n1].CC())<dmin) d=2.*dmin;
	        if (d<dmin){
                linelist[k].ToggleSelect();
                DeleteSelectedSegments();
                AddSegment(n0,i,&segm,dmin);
                AddSegment(i,n1,&segm,dmin);
                i=(int) nodelist.GetSize();
            }

        }
    }

	return TRUE;
}