什么是四叉树?

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

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

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

四叉树的实现

 #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++实现四叉树的更多相关文章

  1. 地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了

    地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了 四叉树对于区域查询,效率比较高. 原理图

  2. HTML5实现3D和2D可视化QuadTree四叉树碰撞检测

    QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有四个孩子节点,可将二维平面递归分割子区域.QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍的是 ...

  3. HT for Web可视化QuadTree四叉树碰撞检测

    QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有四个孩子节点,可将二维平面递归分割子区域.QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍的是 ...

  4. [转]一个四叉树Demo学习

    程序代码: http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C 四叉树: using Sys ...

  5. [转]基于四叉树(QuadTree)的LOD地形实现

    实现基于四叉树的LOD地形时,我遇到的主要问题是如何修补地形裂缝. 本段我将描述使用LOD地形的优势,我实现LOD地形的思路,实现LOD地形核心模块的详细过程,以及修补地形裂缝的思路. 首先,LOD地 ...

  6. 线性四叉树十进制Morton码计算示例

    线性四叉树十进制Morton码计算,具体算法描述龚健雅<地理信息系统基础>P108

  7. 一个四叉树Demo学习

    程序代码: http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C 四叉树: using Sys ...

  8. UVA 297 Quadtrees(四叉树建树、合并与遍历)

    <span style="font-size: 18pt; font-family: Arial, Helvetica, sans-serif; background-color: r ...

  9. [LeetCode] Quad Tree Intersection 四叉树相交

    A quadtree is a tree data in which each internal node has exactly four children: topLeft, topRight,  ...

随机推荐

  1. 读书笔记 effective c++ Item3 在任何可能的时候使用 const

    Const可以修饰什么?   Const 关键字是万能的,在类外部,你可以用它修饰全局的或者命名空间范围内的常量,也可以用它来修饰文件,函数和块作用域的静态常量.在类内部,你可以使用它来声明静态或者非 ...

  2. Raspberry树莓派学习笔记1—基本介绍

    树莓派的简单介绍 一个名片大小的迷你个人电脑主机,还有wifi/蓝牙... 运行完整的Linux操作系统(注意关键字:完整,不是精简过的嵌入式Linux) 开源的硬件平台.与普通主机不同的是,它带有简 ...

  3. 【转】IntelliJ IDEA2016.1 + maven 创建java web 项目

    最近开始使用idea 来写java项目了,这个很流行,相比Eclipse方便了很多.功能多了,相对应的使用的复杂度也较高了,因为网上很多的使用和创建项目的简单教程,都是基于老版本的,每个新版本都有不一 ...

  4. POJ 3356 AGTC(DP求字符串编辑距离)

    给出两个长度小于1000的字符串,有三种操作,插入一个字符,删除一个字符,替换一个字符. 问A变成B所需的最少操作数(即编辑距离) 考虑DP,可以用反证法证明依次从头到尾对A,B进行匹配是不会影响答案 ...

  5. android学习13——android egl hello world

    通常情况下我们使用GLSurfaceview来实现opengl渲染.GLSurfaceview实现上是对SurfaceView和EGL的封装.为了从本质上理解渲染流程,使用EGL和SurfaceVie ...

  6. 对本地Solr服务器添加IK中文分词器实现全文检索功能

    在上一篇随笔中我们提到schema.xml中<field/>元素标签的配置,该标签中有四个属性,分别是name.type.indexed与stored,这篇随笔将讲述通过设置type属性的 ...

  7. 学习JVM--垃圾回收(二)GC收集器

    1. 前言 在上一篇文章中,介绍了JVM中垃圾回收的原理和算法.介绍了通过引用计数和对象可达性分析的算法来筛选出已经没有使用的对象,然后介绍了垃圾收集器中使用的三种收集算法:标记-清除.标记-整理.标 ...

  8. Log日志规范

    Overview 一个在生产环境里运行的程序如果没有日志是很让维护者提心吊胆的,有太多杂乱又无意义的日志也是令人伤神.程序出现问题时候,从日志里如果发现不了问题可能的原因是很令人受挫的.本文想讨论的是 ...

  9. angular : ng-animate : css 原理,详解

    通过几中指令就能完成1.2.xx的animate ·ng-repeat ·ng-show,ng-hide ·ng-if,ng-include,ng-view ·ng-switch ·ng-class ...

  10. cura-engine学习(3)

    目前,我们还在函数prepareModel中徘徊,因为这函数实在是太长了,近乎包含了整个数据处理过程.通过前面两篇,几何图形已经被导入到内存中,并且由一个simplemodel变成了一个optimiz ...