558. 四叉树交集

这篇博客介绍了如何在四叉树中处理逻辑或操作,给出了一种方法来根据两个四叉树创建表示它们交集的四叉树。四叉树用于表示二维空间的划分,并通过递归将其细分为四个区域。解决方案涉及遍历四叉树节点,如果遇到叶节点,返回其值;否则,对每个子节点进行相同操作,最后返回逻辑或结果。
摘要由CSDN通过智能技术生成

四叉树是一种树数据,其中每个结点恰好有四个子结点:topLefttopRightbottomLeft 和 bottomRight。四叉树通常被用来划分一个二维空间,递归地将其细分为四个象限或区域。

我们希望在四叉树中存储 True/False 信息。四叉树用来表示 N * N 的布尔网格。对于每个结点, 它将被等分成四个孩子结点直到这个区域内的值都是相同的。每个节点都有另外两个布尔属性:isLeaf 和 isLeaf。当这个节点是一个叶子结点时 isLeaf 为真。val 变量储存叶子结点所代表的区域的值。

例如,下面是两个四叉树 A 和 B:

A:
+-------+-------+   T: true
|       |       |   F: false
|   T   |   T   |
|       |       |
+-------+-------+
|       |       |
|   F   |   F   |
|       |       |
+-------+-------+
topLeft: T
topRight: T
bottomLeft: F
bottomRight: F

B:               
+-------+---+---+
|       | F | F |
|   T   +---+---+
|       | T | T |
+-------+---+---+
|       |       |
|   T   |   F   |
|       |       |

四叉树是一种常用的空间数据结构,可以用于快速查找、插入和删除二维空间中的对象。下面是使用 C++ 在 Visual Studio 2022 中实现四叉树的示例代码: ```cpp #include <iostream> #include <vector> #include <cmath> using namespace std; // 二维点结构体 struct Point { float x, y; Point(float x = 0, float y = 0) : x(x), y(y) {} }; // 二维矩形结构体 struct Rectangle { Point center; float width, height; Rectangle(Point c = Point(), float w = 0, float h = 0) : center(c), width(w), height(h) {} }; // 四叉树节点 class QuadtreeNode { public: QuadtreeNode(Rectangle rect, int level = 0, int maxLevel = 5, int maxObjects = 10) : m_rect(rect), m_level(level), m_maxLevel(maxLevel), m_maxObjects(maxObjects) {} ~QuadtreeNode(); void insert(Point point); // 插入一个点 vector<Point> query(Rectangle rect); // 查询在指定矩形内的点 private: Rectangle m_rect; // 节点表示的矩形区域 int m_level; // 节点深度 int m_maxLevel; // 最大深度 int m_maxObjects; // 最大存储对象数目 vector<Point> m_points; // 存储当前节点包含的所有点 QuadtreeNode* m_children[4] = { nullptr }; // 存储四个子节点 int getIndex(Point point); // 获取点所在子节点的索引 void split(); // 分裂当前节点 }; QuadtreeNode::~QuadtreeNode() { for (int i = 0; i < 4; i++) { if (m_children[i] != nullptr) { delete m_children[i]; m_children[i] = nullptr; } } } void QuadtreeNode::insert(Point point) { if (m_children[0] != nullptr) { // 如果有子节点,则将点添加到子节点中 int index = getIndex(point); if (index != -1) { m_children[index]->insert(point); return; } } m_points.push_back(point); // 否则将点添加到当前节点中 if (m_points.size() > m_maxObjects && m_level < m_maxLevel) { // 如果当前节点存储的点数超过了最大值,并且当前深度小于最大深度,则分裂当前节点 if (m_children[0] == nullptr) { split(); } int i = 0; while (i < m_points.size()) { int index = getIndex(m_points[i]); if (index != -1) { m_children[index]->insert(m_points[i]); m_points.erase(m_points.begin() + i); } else { i++; } } } } vector<Point> QuadtreeNode::query(Rectangle rect) { vector<Point> result; if (m_rect.center.x - m_rect.width / 2 > rect.center.x + rect.width / 2 || m_rect.center.x + m_rect.width / 2 < rect.center.x - rect.width / 2 || m_rect.center.y - m_rect.height / 2 > rect.center.y + rect.height / 2 || m_rect.center.y + m_rect.height / 2 < rect.center.y - rect.height / 2) { // 如果矩形与当前节点表示的矩形没有交集,则直接返回空结果 return result; } for (Point p : m_points) { if (p.x >= rect.center.x - rect.width / 2 && p.x <= rect.center.x + rect.width / 2 && p.y >= rect.center.y - rect.height / 2 && p.y <= rect.center.y + rect.height / 2) { // 如果点在矩形范围内,则将其加入结果中 result.push_back(p); } } if (m_children[0] != nullptr) { // 如果有子节点,则递归查询子节点 for (int i = 0; i < 4; i++) { vector<Point> childResult = m_children[i]->query(rect); result.insert(result.end(), childResult.begin(), childResult.end()); } } return result; } int QuadtreeNode::getIndex(Point point) { if (point.x < m_rect.center.x && point.y < m_rect.center.y) { return 0; } else if (point.x >= m_rect.center.x && point.y < m_rect.center.y) { return 1; } else if (point.x < m_rect.center.x && point.y >= m_rect.center.y) { return 2; } else if (point.x >= m_rect.center.x && point.y >= m_rect.center.y) { return 3; } else { return -1; } } void QuadtreeNode::split() { float halfWidth = m_rect.width / 2; float halfHeight = m_rect.height / 2; m_children[0] = new QuadtreeNode(Rectangle(Point(m_rect.center.x - halfWidth / 2, m_rect.center.y - halfHeight / 2), halfWidth, halfHeight), m_level + 1, m_maxLevel, m_maxObjects); m_children[1] = new QuadtreeNode(Rectangle(Point(m_rect.center.x + halfWidth / 2, m_rect.center.y - halfHeight / 2), halfWidth, halfHeight), m_level + 1, m_maxLevel, m_maxObjects); m_children[2] = new QuadtreeNode(Rectangle(Point(m_rect.center.x - halfWidth / 2, m_rect.center.y + halfHeight / 2), halfWidth, halfHeight), m_level + 1, m_maxLevel, m_maxObjects); m_children[3] = new QuadtreeNode(Rectangle(Point(m_rect.center.x + halfWidth / 2, m_rect.center.y + halfHeight / 2), halfWidth, halfHeight), m_level + 1, m_maxLevel, m_maxObjects); } ``` 下面是一个简单的测试程序,用于演示如何使用四叉树进行点的查询: ```cpp int main() { QuadtreeNode root(Rectangle(Point(0, 0), 100, 100)); // 插入一些点 root.insert(Point(10, 10)); root.insert(Point(20, 20)); root.insert(Point(30, 30)); root.insert(Point(40, 40)); root.insert(Point(50, 50)); root.insert(Point(60, 60)); root.insert(Point(70, 70)); root.insert(Point(80, 80)); root.insert(Point(90, 90)); // 查询指定矩形内的点 vector<Point> result = root.query(Rectangle(Point(45, 45), 20, 20)); // 输出查询结果 cout << "query result:" << endl; for (Point p : result) { cout << "(" << p.x << ", " << p.y << ")" << endl; } return 0; } ``` 上述代码中,首先创建一个根节点,然后向其中插入一些点,最后查询指定矩形内的点,并输出查询结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值