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(): _rect(rect)
{
STD queue<Tree4 *> queue;
queue.push(this);
; n != ; --n, c *= )
{
; 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;
};
代码简洁,通俗易懂,承让。
效果图

左侧全图遍历,右侧四叉树遍历,通过左上角的开销时间,差异很明显。
C++实现四叉树的更多相关文章
- 地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了
地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了 四叉树对于区域查询,效率比较高. 原理图
- HTML5实现3D和2D可视化QuadTree四叉树碰撞检测
QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有四个孩子节点,可将二维平面递归分割子区域.QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍的是 ...
- HT for Web可视化QuadTree四叉树碰撞检测
QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有四个孩子节点,可将二维平面递归分割子区域.QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍的是 ...
- [转]一个四叉树Demo学习
程序代码: http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C 四叉树: using Sys ...
- [转]基于四叉树(QuadTree)的LOD地形实现
实现基于四叉树的LOD地形时,我遇到的主要问题是如何修补地形裂缝. 本段我将描述使用LOD地形的优势,我实现LOD地形的思路,实现LOD地形核心模块的详细过程,以及修补地形裂缝的思路. 首先,LOD地 ...
- 线性四叉树十进制Morton码计算示例
线性四叉树十进制Morton码计算,具体算法描述龚健雅<地理信息系统基础>P108
- 一个四叉树Demo学习
程序代码: http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C 四叉树: using Sys ...
- UVA 297 Quadtrees(四叉树建树、合并与遍历)
<span style="font-size: 18pt; font-family: Arial, Helvetica, sans-serif; background-color: r ...
- [LeetCode] Quad Tree Intersection 四叉树相交
A quadtree is a tree data in which each internal node has exactly four children: topLeft, topRight, ...
随机推荐
- 最新升级的火狐38.0.6识别ajax调用返回的""空值可能有异常。
自已在调用一段ajax开发中,返回的是空值 string result = string.Empty;return result; 但在页面进行$.ajax调用 时 输出alert(result);应 ...
- 关于ionic开发的一些总结(项目启动设置,app图标名称更改)
1.更改包名称 一般项目刚生成时,ionic会根据项目名称自动给你生成一个包名.要修改包名的话,在根目录的config配置文件中,<widget id="x.x.x"换成自己 ...
- java udp socket(双通信)
参考博客:http://blog.csdn.net/wintys/article/details/3525643/,非常感谢 实现功能:客户端发送字符串A ->服务端接收并显示在控制台 ...
- 【Spring】使用Spring的AbstractRoutingDataSource实现多数据源切换
最近因为项目需要在做两个项目间数据同步的需求,具体是项目1的数据通过消息队列同步到项目2中,因为这个更新操作还涉及到更新多个库的数据,所以就需要多数据源切换的操作.下面就讲讲在Spring中如何进行数 ...
- 用phpcms如何将静态页面制作成企业网站,头部加尾部
首先,先要准备好这个静态网页的源文件,如图 bs里面是一些css和js的文件,img则是放图片的,文件中的index是网页的首页 运行一下,看看 是这样的 然后打开phpcms文件,上篇博客中有提到, ...
- GCD(关于容斥原理)
Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD( ...
- ES6__异步开发优化
一:JS事件循环 1:同步调用 同步调用是一种阻塞式调用,调用要等待双方执行完毕才返回,他是一种单向调用. 2:回调 回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口. 3: ...
- Vue.js 系列教程 5:动画
原文:intro-to-vue-5-animations 译者:nzbin 译者的话:经过两周的努力,终于完成了这个系列的翻译,由于时间因素及个人水平有限,并没有详细的校对,其中仍然有很多不易理解的地 ...
- 四色GDOI&GDOI2015滚粗记
好吧自己太弱写不了什么四色NOI只能学学别人写个四色GDOI了...首先自己还是太弱所以就被学校卡了个名额就进不了省队了QAQ.自己GDOI觉得考得不错可是NOIP毕竟少了人家5分根本追不上去好不QA ...
- BZOJ 1877: [SDOI2009]晨跑(费用流)
看到要求两个量就下意识的想到了费用流= =,先把一个点拆成两个点就能够解决一个的只经过一次的限制 CODE: #include<cstdio>#include<iostream> ...