我使用四叉树作为数据结构来存储点,因为我需要快速地找到特定区域内的所有点。但是我需要移动这些点,在我的 C++ 程序中,由于每个点移动的方向不同,所以我目前要销毁并重新构建四叉树,这会导致大量的分配和删除。
因此,我的问题是:是否有更好的数据结构来解决这种问题?
我有以下需求: - 我有 n 个点。 - 我需要快速地获取给定区域内的所有点。使用四叉树,时间复杂度大约为 O(log(n))。但是这个操作会被执行 m 次,其中 m > n,因此时间复杂度约为 O(m*log(n))。 - 我需要移动所有点。目前,这需要大约 O(n*logn) 的时间。该方法仅在所有 m 中调用一次。
然而,我发现目前的解决方案令人不满意。因为我总是销毁并重建四叉树,这会导致由于分配而产生额外的开销。
更新: 这些点的分布不均匀。有些位置密集,有些位置很少有点。
以下是一些简化代码。这里是存储指针的代码:
这是四叉树的接口。
因此,我的问题是:是否有更好的数据结构来解决这种问题?
我有以下需求: - 我有 n 个点。 - 我需要快速地获取给定区域内的所有点。使用四叉树,时间复杂度大约为 O(log(n))。但是这个操作会被执行 m 次,其中 m > n,因此时间复杂度约为 O(m*log(n))。 - 我需要移动所有点。目前,这需要大约 O(n*logn) 的时间。该方法仅在所有 m 中调用一次。
然而,我发现目前的解决方案令人不满意。因为我总是销毁并重建四叉树,这会导致由于分配而产生额外的开销。
更新: 这些点的分布不均匀。有些位置密集,有些位置很少有点。
以下是一些简化代码。这里是存储指针的代码:
class Point
{
public:
Point(double x, double y):x(x),y(y){};
void movePoint(double ux, double uy);
double x;
double y;
};
这是四叉树的接口。
class QuadTree
{
public:
QuadTree(double north, double west, double south, double east,
int maxItems);
//inserts a point into the tree runs in log(n)
bool put(Point* pt);
// returns all point in the rectange defined by the four variables runs in log(n)
std::vector<Point*> get(double north, double west, double south, double east);
// deletes everything in the quad tree
void clear();
private:
QuadTreeNode* top_=nullptr;
};
以下是QuadTreeNode接口的get和put方法实现,以展示如何存储Point。
class QuadTreeNode
{
public:
QuadTreeNode(double north, double west, double south, double east,
int maximumItems);
~QuadTreeNode();
//split the node if to much items are stored.
void split();
//returns the children of the node
QuadTreeNode* getChild(double x, double y);
bool put(Point* leaf){
if (children_ == nullptr) {
items_.push_back(leaf);
if (items_.size() > maxItems_)
split();
return true;
} else {
QuadTreeNode* node = getChild(leaf->getX(), leaf->getY());
if (node != nullptr) {
return node->put(leaf);
}
}
return false;
}
std::vector<Point*> QuadTreeNode::get(QuadRectangle rect, std::vector<Point*>& vector) {
if (children_ == nullptr) {
for (Point* pt : items_) {
if (rect.pointWithinBounds(pt->getX(),pt->getY())) {
vector.push_back(pt);
}
}
} else {
for (QuadTreeNode* child : *children_) {
if (child->bounds_.within(rect)) {
child->get(rect, vector);
}
}
}
return vector;
}
std::vector<Point*> items_;
unsigned int maxItems_;
std::array<QuadTreeNode*,4>* children_ = nullptr;
QuadRectangle bounds_;
};