I am trying to build a KD Tree (static register). Suppose the points are sorted by x and y coordinates.
For an even recursion depth, the set is divided into two subsets with a vertical line passing through the median coordinate x.
With an odd depth of recursion, the set is divided into two subsets with a horizontal line passing through the middle coordinate y.
The median can be determined from the sorted set in accordance with the x / y coordinate. I take this step before each partition of the set. And I think this causes a slow tree build.
- Please, could you help me verify and optimize the code?
- I can't find the kth closest neighbor, can someone help me with the code?
Thank you very much for your help and patience ...
See sample code:
class KDNode
{
private:
Point2D *data;
KDNode *left;
KDNode *right;
....
};
void KDTree::createKDTree(Points2DList *pl)
{
KDList kd_list;
for (unsigned int i = 0; i < pl->size(); i++)
{
kd_list.push_back((*pl)[i]);
}
std::sort(kd_list.begin(), kd_list.end(), sortPoints2DByY());
root = buildKDTree(&kd_list, 1);
}
KDNode * KDTree::buildKDTree(KDList *kd_list, const unsigned int depth)
{
const unsigned int n = kd_list->size();
if (n == 0)
{
return NULL;
}
else if (n == 1)
{
return new KDNode(new Point2D ((*kd_list)[0]));
}
else
{
KDNode *node = NULL;
const unsigned int median_index = n/2;
KDList kd_list1, kd_list2;
if (depth%2 == 0)
{
node = new KDNode(new Point2D( (*kd_list)[median_index]));
for (unsigned int i = 0; i < n; i++)
{
Point2D *p = &(*kd_list)[i];
if (p->getX() < (*kd_list)[median_index].getX())
{
kd_list1.push_back(*p);
}
else if (p->getX() > (*kd_list)[median_index].getX())
{
kd_list2.push_back(*p);
}
}
std::sort(kd_list1.begin(), kd_list1.end(), sortPoints2DByY());
std::sort(kd_list2.begin(), kd_list2.end(), sortPoints2DByY());
}
else
{
node = new KDNode(new Point2D((*kd_list)[median_index]));
for (unsigned int i = 0; i < n; i++)
{
Point2D *p = &(*kd_list)[i];
if (p->getY() < (*kd_list)[median_index].getY())
{
kd_list1.push_back(*p);
}
else if (p->getY() >(*kd_list)[median_index].getY())
{
kd_list2.push_back(*p);
}
}
std::sort(kd_list1.begin(), kd_list1.end(), sortPoints2DByX());
std::sort(kd_list2.begin(), kd_list2.end(), sortPoints2DByX());
}
node->setLeft( buildKDTree(&kd_list1, depth +1 ) );
node->setRight( buildKDTree(&kd_list2, depth + 1 ) );
return node;
}
}