Welcome, guest! Login / Register - Why register?
Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)

Paste

Pasted as C by Forrest_chen ( 14 years ago )
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define INF 0x0ffffff
typedef unsigned int bool;
#define true 1
#define false 0
typedef enum Level{vertical, horizontal}Level;
//K=2 for this program, 2-dimensional tree

typedef struct Point{
 int x, y;
}Point;

Level numToLevel(int v){
 if(v==0)return vertical;
 else return horizontal;
}

bool pointInRectangle(Point p, Point p1, Point p2){
 if(p.x>p1.x && p.x<p2.x && p.y>p1.y && p.y<p2.y)return true;
 return false;
}

typedef struct KDTreeNode{
 Point p;
 struct KDTreeNode* leftORdown;
 struct KDTreeNode* rightORup;
 Level level; //use enum really make it more readable?
}KDTreeNode,*KDTree;

void KDTreeInsert(KDTree *root, Point p){
 if((*root)==NULL){
  (*root) = (KDTree)malloc(sizeof(KDTreeNode));
  (*root)->leftORdown=(*root)->rightORup=NULL;
  (*root)->level=vertical;
  (*root)->p=p;
 } else {
  //TODO
  KDTree tmpRoot = (*root);
  int level=0;
  KDTree child;
  if(p.x<(*root)->p.x){
   child = (*root)->leftORdown;
  }else{
   child = (*root)->rightORup;
  }
  while(child != NULL){
   tmpRoot = child;
   level = (level+1)%2;
   if((level==0 && p.x<tmpRoot->p.x) || (level==1 && p.y<tmpRoot->p.y)){
    child = tmpRoot->leftORdown;
   } else {
    child = tmpRoot->rightORup;
   }
  }
  child = (KDTree)malloc(sizeof(KDTreeNode));
  child->leftORdown = child->rightORup = NULL;
  child->p = p;
  child->level = numToLevel((level+1)%2);
  if((level==0 && p.x<tmpRoot->p.x) || (level==1 && p.y<tmpRoot->p.y)){
   tmpRoot->leftORdown = child;
  } else {
   tmpRoot->rightORup = child;
  }
 }
}

KDTree KDTreeInsert_Recursion(KDTree root, Point p, int level){
 if(root==NULL){
  root = (KDTree)malloc(sizeof(KDTreeNode));
  root->leftORdown=root->rightORup=NULL;
  root->level=numToLevel(level);
  root->p=p;
  return root;
 } else {
  if(level==0){
   if(p.x<root->p.x){
    root->leftORdown = KDTreeInsert_Recursion(root->leftORdown,p,1);
    return root;
   }else{
    root->rightORup = KDTreeInsert_Recursion(root->rightORup,p,1);
    return root;
   }
  } else {
   if(p.y<root->p.y){
    root->leftORdown = KDTreeInsert_Recursion(root->leftORdown,p,0);
    return root;
   }else{
    root->rightORup = KDTreeInsert_Recursion(root->rightORup,p,0);
    return root;
   }
  }
 }
}

void KDTreeQueryInRectangle(KDTree root, Point p1, Point p2, int level){
 if(root==NULL)return;
 if(pointInRectangle(root->p,p1,p2)){
  printf("x=%d y=%d\n",root->p.x,root->p.y);
 }
 if(level==0){
  if(p1.x<root->p.x){
   KDTreeQueryInRectangle(root->leftORdown,p1,p2,1);
  }
  if(p2.x>root->p.x){
   KDTreeQueryInRectangle(root->rightORup,p1,p2,1);
  }
 } else {
  if(p1.y<root->p.y){
   KDTreeQueryInRectangle(root->leftORdown,p1,p2,0);
  }
  if(p2.y>root->p.y){
   KDTreeQueryInRectangle(root->rightORup,p1,p2,0);
  }
 }
}

//TODO: Need some optimizing...
// because the minimal distance from a point to a point in rectangle is not all the vertical/horizontal distance
int distanceSqr(Point p1, Point p2){
 return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
int recentMin=INF;
void findNearestPoint(KDTree root, Point p, int level){
 if(root==NULL)return;
 if(distanceSqr(root->p,p)<recentMin)recentMin = distanceSqr(root->p,p);
 if(level==0){
  if(p.x<root->p.x){
   findNearestPoint(root->leftORdown,p,1);
   if(recentMin>(p.x-root->p.x)*(p.x-root->p.x)){
    findNearestPoint(root->rightORup,p,1);
   }
  } else {
   findNearestPoint(root->rightORup,p,1);
   if(recentMin>(p.x-root->p.x)*(p.x-root->p.x)){
    findNearestPoint(root->leftORdown,p,1);
   }
  }
 } else {
  if(p.y<root->p.y){
   findNearestPoint(root->leftORdown,p,0);
   if(recentMin>(p.y-root->p.y)*(p.y-root->p.y)){
    findNearestPoint(root->rightORup,p,0);
   }
  } else {
   findNearestPoint(root->rightORup,p,0);
   if(recentMin>(p.y-root->p.y)*(p.y-root->p.y)){
    findNearestPoint(root->leftORdown,p,0);
   }
  }
 }
}

int main(int argc, char const *argv[])
{
 int i;
 int dx[]={1};
 int dy[]={1};
 KDTree root = NULL;
 
 return 0;
}

 

Revise this Paste

Your Name: Code Language: