找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 173|回复: 0

C++实现四叉树

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-3-8 16:28:36 | 显示全部楼层 |阅读模式
  1. 四叉树可以有效解决这个问题。
  2. 树的每一层都把地图划分四块,根据地图尺寸来决定树的层数,层数越大划分越细。
  3. 当需要对某一范围的单位筛选时,只需要定位到与范围相交的树区域,再对其区域内的对象筛选即可。
  4. 代码如下:
  5. #pragma once
  6.   
  7. #include "base.h"
  8. #include "math.h"
  9.   
  10. template <class Value>
  11. class Tree4 {
  12. private:
  13. struct Pointer {
  14. Tree4 *LT, *RT, *LB, *RB;
  15. Pointer() :LT(nullptr), RT(nullptr), LB(nullptr), RB(nullptr)
  16. { }
  17. ~Pointer()
  18. {
  19. SAFE采用DELETE(LT);
  20. SAFE采用DELETE(RT);
  21. SAFE采用DELETE(LB);
  22. SAFE采用DELETE(RB);
  23. }
  24. };
  25.   
  26. public:
  27. Tree4(const MATH Rect &rect, size采用t n = 0): 采用rect(rect)
  28. {
  29. STD queue<Tree4 *> queue;
  30. queue.push(this);
  31. for (auto c = 1; n != 0; --n, c *= 4)
  32. {
  33. for (auto i = 0; i != c; ++i)
  34. {
  35. auto tree = queue.front();
  36. tree->Root();
  37. queue.pop();
  38. queue.push(tree->采用pointer.LT);
  39. queue.push(tree->采用pointer.RT);
  40. queue.push(tree->采用pointer.LB);
  41. queue.push(tree->采用pointer.RB);
  42. }
  43. }
  44. }
  45.   
  46. template <class Range>
  47. bool Insert(const Value * value, const Range & range)
  48. {
  49. auto tree = Contain(range);
  50. auto ret = nullptr != tree;
  51. if (ret) { tree->采用values.emplace采用back(value); }
  52. return ret;
  53. }
  54.   
  55. template <class Range>
  56. bool Remove(const Value * value, const Range & range)
  57. {
  58. auto tree = Contain(range);
  59. auto ret = nullptr != tree;
  60. if (ret) { ret = tree->Remove(value); }
  61. return ret;
  62. }
  63.   
  64. template <class Range>
  65. bool Match(const Range & range, const STD function<bool(Value *)> & func)
  66. {
  67. if (!MATH intersect(采用rect, range))
  68. {
  69. return true;
  70. }
  71.   
  72. for (auto & value : 采用values)
  73. {
  74. if (!func(const采用cast<Value *>(value)))
  75. {
  76. return false;
  77. }
  78. }
  79.   
  80. auto ret = true;
  81. if (!IsLeaf())
  82. {
  83. if (ret) ret = 采用pointer.LT->Match(range, func);
  84. if (ret) ret = 采用pointer.RT->Match(range, func);
  85. if (ret) ret = 采用pointer.LB->Match(range, func);
  86. if (ret) ret = 采用pointer.RB->Match(range, func);
  87. }
  88. return ret;
  89. }
  90.   
  91. template <class Range>
  92. Tree4 * Contain(const Range & range)
  93. {
  94. Tree4<Value> * ret = nullptr;
  95. if (MATH contain(STD cref(采用rect), range))
  96. {
  97. if (!IsLeaf())
  98. {
  99. if (nullptr == ret) ret = 采用pointer.LT->Contain(range);
  100. if (nullptr == ret) ret = 采用pointer.RT->Contain(range);
  101. if (nullptr == ret) ret = 采用pointer.LB->Contain(range);
  102. if (nullptr == ret) ret = 采用pointer.RB->Contain(range);
  103. }
  104. if (nullptr == ret)
  105. ret = this;
  106. }
  107. return ret;
  108. }
  109.   
  110. private:
  111. void Root()
  112. {
  113. 采用pointer.LT = new Tree4(MATH Rect(采用rect.x, 采用rect.y, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
  114. 采用pointer.LB = new Tree4(MATH Rect(采用rect.x, 采用rect.y + 采用rect.h * 0.5f, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
  115. 采用pointer.RT = new Tree4(MATH Rect(采用rect.x + 采用rect.w * 0.5f, 采用rect.y, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
  116. 采用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));
  117. }
  118.   
  119. bool Remove(const Value * value)
  120. {
  121. auto iter = STD find(采用values.begin(), 采用values.end(), value);
  122. auto ret = 采用values.end() != iter;
  123. if (ret) { 采用values.erase(iter); }
  124. return ret;
  125. }
  126.   
  127. bool IsLeaf()
  128. {
  129. return nullptr == 采用pointer.LT
  130. || nullptr == 采用pointer.RT
  131. || nullptr == 采用pointer.LB
  132. || nullptr == 采用pointer.RB;
  133. }
  134.   
  135. Tree4(const Tree4 &) = delete;
  136. Tree4(Tree4 &&) = delete;
  137. Tree4 &operator=(const Tree4 &) = delete;
  138. Tree4 &operator=(Tree4 &&) = delete;
  139.   
  140. private:
  141. MATH Rect 采用rect;
  142. Pointer 采用pointer;
  143. STD list<const Value *> 采用values;
  144. };
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-28 14:01 , Processed in 0.209643 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表