admin 发表于 2024-3-8 16:28:36

C++实现四叉树

四叉树可以有效解决这个问题。

树的每一层都把地图划分四块,根据地图尺寸来决定树的层数,层数越大划分越细。

当需要对某一范围的单位筛选时,只需要定位到与范围相交的树区域,再对其区域内的对象筛选即可。

代码如下:

#pragma once

#include "base.h"
#include "math.h"

template <class Value>
class Tree4 {
private:
struct Pointer {
Tree4 *LT, *RT, *LB, *RB;
Pointer() :LT(nullptr), RT(nullptr), LB(nullptr), RB(nullptr)
{ }
~Pointer()
{
SAFE采用DELETE(LT);
SAFE采用DELETE(RT);
SAFE采用DELETE(LB);
SAFE采用DELETE(RB);
}
};

public:
Tree4(const MATH Rect &rect, size采用t n = 0): 采用rect(rect)
{
STD queue<Tree4 *> queue;
queue.push(this);
for (auto c = 1; n != 0; --n, c *= 4)
{
for (auto i = 0; i != c; ++i)
{
auto tree = queue.front();
tree->Root();
queue.pop();
queue.push(tree->采用pointer.LT);
queue.push(tree->采用pointer.RT);
queue.push(tree->采用pointer.LB);
queue.push(tree->采用pointer.RB);
}
}
}

template <class Range>
bool Insert(const Value * value, const Range & range)
{
auto tree = Contain(range);
auto ret = nullptr != tree;
if (ret) { tree->采用values.emplace采用back(value); }
return ret;
}

template <class Range>
bool Remove(const Value * value, const Range & range)
{
auto tree = Contain(range);
auto ret = nullptr != tree;
if (ret) { ret = tree->Remove(value); }
return ret;
}

template <class Range>
bool Match(const Range & range, const STD function<bool(Value *)> & func)
{
if (!MATH intersect(采用rect, range))
{
return true;
}

for (auto & value : 采用values)
{
if (!func(const采用cast<Value *>(value)))
{
return false;
}
}

auto ret = true;
if (!IsLeaf())
{
if (ret) ret = 采用pointer.LT->Match(range, func);
if (ret) ret = 采用pointer.RT->Match(range, func);
if (ret) ret = 采用pointer.LB->Match(range, func);
if (ret) ret = 采用pointer.RB->Match(range, func);
}
return ret;
}

template <class Range>
Tree4 * Contain(const Range & range)
{
Tree4<Value> * ret = nullptr;
if (MATH contain(STD cref(采用rect), range))
{
if (!IsLeaf())
{
if (nullptr == ret) ret = 采用pointer.LT->Contain(range);
if (nullptr == ret) ret = 采用pointer.RT->Contain(range);
if (nullptr == ret) ret = 采用pointer.LB->Contain(range);
if (nullptr == ret) ret = 采用pointer.RB->Contain(range);
}
if (nullptr == ret)
ret = this;
}
return ret;
}

private:
void Root()
{
采用pointer.LT = new Tree4(MATH Rect(采用rect.x, 采用rect.y, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
采用pointer.LB = new Tree4(MATH Rect(采用rect.x, 采用rect.y + 采用rect.h * 0.5f, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
采用pointer.RT = new Tree4(MATH Rect(采用rect.x + 采用rect.w * 0.5f, 采用rect.y, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
采用pointer.RB = new Tree4(MATH Rect(采用rect.x + 采用rect.w * 0.5f, 采用rect.y + 采用rect.h * 0.5f, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
}

bool Remove(const Value * value)
{
auto iter = STD find(采用values.begin(), 采用values.end(), value);
auto ret = 采用values.end() != iter;
if (ret) { 采用values.erase(iter); }
return ret;
}

bool IsLeaf()
{
return nullptr == 采用pointer.LT
|| nullptr == 采用pointer.RT
|| nullptr == 采用pointer.LB
|| nullptr == 采用pointer.RB;
}

Tree4(const Tree4 &) = delete;
Tree4(Tree4 &&) = delete;
Tree4 &operator=(const Tree4 &) = delete;
Tree4 &operator=(Tree4 &&) = delete;

private:
MATH Rect 采用rect;
Pointer 采用pointer;
STD list<const Value *> 采用values;
};
页: [1]
查看完整版本: C++实现四叉树