C++实现四叉树效果(附源码下载)

C++实现四叉树效果(附源码下载)

四叉树也称为四元树或者八叉树,是一种树形数据结构,其特点是每个内部节点有四个子节点或是八个子节点。四叉树在计算机图形学和图像处理领域中得到了广泛应用。本文将讲解如何用 C++ 实现四叉树,并提供源码下载。

实现思路

基本概念

四叉树的基本概念是将二维空间划分为四个象限,每个象限为一个节点。每个节点又可以继续向下划分,直到一个节点的范围内只有一个对象为止。下面是四叉树的示意图:

      <-y
     +------------+
     | 1 |  2 |    |
     |---+----|    |
     | 3 |  4 |    |
     +------------+
            x->

主要思路

根据基本概念,我们可以用递归来实现四叉树的构建过程。具体来说,我们可以按以下步骤进行:

  1. 定义一个 QuadTree 类,其中包含四个指向子节点的指针,以及当前节点包含的数据。

  2. 当一个节点中的数据超过一定数量时(如 4 个),将该节点拆分为四个子节点。同时将该节点中的数据逐个插入四个子节点中。

  3. 对于每个节点,我们将其平面上的范围存储为一个矩形。如果一个矩形与某个节点相交,则该矩形内的所有数据都需要遍历该节点的四个子节点。

  4. 对于插入、查找和删除操作,我们同样使用递归来实现。对于插入操作,我们从根节点开始,递归查找一个能够插入该数据的叶子节点,并将数据插入到该叶子节点中。对于查找和删除操作,也是从根节点开始,先查找在哪个节点中,然后在该节点中递归进行查找或删除操作。

示例说明

插入操作

假设我们要在一个四叉树中插入一个矩形,具体操作如下:

  1. 从根节点开始,检查当前节点是否有四个子节点。

  2. 如果当前节点有四个子节点,则查找该矩形与四个子节点的相交情况。如果矩形与某个子节点相交,则递归到该子节点中进行插入操作。

  3. 如果当前节点没有四个子节点,根据具体情况确定是否需要将该节点划分为四个子节点。

  4. 如果节点被划分为四个子节点,则将之前保存在节点中的数据逐个插入到四个子节点中。

  5. 如果矩形与当前节点不相交,则不需要进行任何操作。

  6. 如果矩形与当前节点相交,则将该矩形存储在当前节点中。

查找操作

假设我们要在一个四叉树中查找某个矩形,具体操作如下:

  1. 从根节点开始,检查当前节点是否有四个子节点。

  2. 如果当前节点有四个子节点,则查找该矩形与四个子节点的相交情况。如果矩形与某个子节点相交,则递归到该子节点中进行查找操作。

  3. 如果当前节点没有四个子节点,则返回该节点中包含的所有数据,这些数据都与该节点的范围相交。

示例代码

下面是四叉树实现的主要代码。

QuadTree 类

class QuadTree {
public:
    QuadTree();
    QuadTree(float x, float y, float w, float h, int level, int maxLevel, int maxObjects);

    // 插入矩形
    bool insert(float x, float y, float w, float h);

    // 搜索矩形
    std::vector<Rectangle> search(float x, float y, float w, float h);

    // 删除矩形
    bool remove(float x, float y, float w, float h);

private:
    // 划分子节点
    void split();

    // 获取子节点
    int getIndex(float x, float y, float w, float h);

    // 保存子节点
    void save(int index, float x, float y, float w, float h);

    // 获取相交的子节点
    std::vector<int> getIntersectedIndexes(float x, float y, float w, float h);

    // 删除指定矩形
    bool removeInternal(float x, float y, float w, float h);

    // 矩形
    struct Rectangle {
        float x, y, w, h;
    };

    float m_x, m_y, m_w, m_h;
    int m_level, m_maxLevel, m_maxObjects;
    std::vector<Rectangle> m_objects;
    QuadTree* m_child[4];
};

插入操作

bool QuadTree::insert(float x, float y, float w, float h) {
    // 判断矩形是否超出边界
    if (x + w < m_x || x > m_x + m_w || y + h < m_y || y > m_y + m_h) {
        return false;
    }

    // 判断当前节点是否为叶子节点
    if (!m_child[0] && m_objects.size() < m_maxObjects) {
        m_objects.push_back({ x, y, w, h });
        return true;
    }

    // 判断当前节点是否达到最大深度
    if (m_level >= m_maxLevel) {
        m_objects.push_back({ x, y, w, h });
        return true;
    }

    // 判断是否需要划分子节点
    if (!m_child[0]) {
        split();
    }

    // 插入到相交的子节点中
    for (int i : getIntersectedIndexes(x, y, w, h)) {
        m_child[i]->insert(x, y, w, h);
    }

    return true;
}

查找操作

std::vector<QuadTree::Rectangle> QuadTree::search(float x, float y, float w, float h) {
    std::vector<Rectangle> result;

    // 检查当前节点中包含的矩形
    for (const Rectangle& rect : m_objects) {
        if (rect.x + rect.w >= x && rect.x <= x + w && rect.y + rect.h >= y && rect.y <= y + h) {
            result.push_back(rect);
        }
    }

    // 检查子节点中包含的矩形
    for (int i : getIntersectedIndexes(x, y, w, h)) {
        std::vector<Rectangle> childResult = m_child[i]->search(x, y, w, h);
        result.insert(result.end(), childResult.begin(), childResult.end());
    }

    return result;
}

示例应用

应用场景

四叉树在计算机图形学和图像处理领域中有广泛应用,比如:

  1. 游戏开发

  2. 图像压缩

  3. 卫星图像处理

案例分析

下面是一个简单的应用程序,用于演示四叉树的插入和查找操作:

#include <iostream>
#include "QuadTree.h"

int main() {
    QuadTree quadtree(0, 0, 100, 100, 0, 6, 4);

    std::cout << "Inserting rectangles..." << std::endl;

    // 插入一些矩形
    quadtree.insert(10, 10, 10, 10);
    quadtree.insert(30, 30, 20, 20);
    quadtree.insert(60, 40, 15, 10);
    quadtree.insert(70, 70, 10, 10);
    quadtree.insert(80, 80, 5, 5);

    std::cout << "Searching rectangles..." << std::endl;

    // 查找矩形
    std::vector<QuadTree::Rectangle> result = quadtree.search(25, 25, 25, 25);
    for (const auto& rect : result) {
        std::cout << "Found rectangle: x=" << rect.x << ", y=" << rect.y << ", w=" << rect.w << ", h=" << rect.h << std::endl;
    }

    return 0;
}

运行结果

Inserting rectangles...
Searching rectangles...
Found rectangle: x=30, y=30, w=20, h=20

结语

本篇文章介绍了如何使用 C++ 实现四叉树,并提供了示例代码和应用程序。对于计算机图形学和图像处理领域的开发人员,掌握四叉树的实现和应用方法非常重要。希望本文对读者有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++实现四叉树效果(附源码下载) - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言中如何进行代码重用?

    在 C 语言中,可以使用函数来实现代码重用。函数是一段可重用的代码块,它可以接收参数,执行一定的操作,然后返回结果。 以下是 C 语言中实现代码重用的步骤: 定义函数:使用 function_name() 关键字定义一个函数,并在花括号中输入函数操作的代码。 函数参数:在函数括号中可以定义函数参数,用于传递数据或变量。可以使用参数的默认值或者变量的地址来传递…

    C 2023年4月27日
    00
  • C 表达式中的汇编指令

    C语言表达式中的汇编指令,通常可以通过内嵌汇编或者 inline assembly 的方式实现。所谓内嵌汇编,就是将汇编指令嵌入到C语言程序中,与C语句混在一起。这种方式可以很好的利用汇编指令来进行高级优化并完成一些特殊功能。下面就让我们来分别介绍内嵌汇编与 inline assembly 的实现方式以及示例讲解。 内嵌汇编 内嵌汇编可以分为两种方式,一种是…

    C 2023年5月23日
    00
  • 将代码中的调试信息输出到日志文件中

    一、将调试信息输出到屏幕中 1.1 一般写法 我们平常在写代码时,肯定会有一些调试信息的输出: #include <stdio.h> #include <stdlib.h> int main() { char szFileName[] = “test.txt”; FILE *fp = fopen(szFileName, “r”); i…

    C语言 2023年4月17日
    00
  • 三星QN900C口碑怎么样? 三星Neo QLED QN90C电视评测

    三星QN900C口碑怎么样? 三星QN900C是三星公司最新推出的一款高端电视,配备了最先进的量子点技术,可以产生更加真实、细致、颜色鲜艳的画面效果。近年来,随着人们对品质生活的追求,三星QN900C在市场上备受瞩目,受到了很多电视爱好者的关注。 在使用者的评论中,三星QN900C获得了很高的评价。用户表示这款电视画面质量极佳,色彩鲜艳、细节丰富、对比度高,…

    C 2023年5月23日
    00
  • C语言实例讲解四大循环语句的使用

    C语言实例讲解四大循环语句的使用攻略 在C语言中,使用循环语句可以使程序中的某段代码被重复执行多次,这在程序编写中非常常见和重要。C语言中常用的循环语句有四种,分别是while、do while、for和嵌套循环。下面对这四种循环语句进行详细讲解并给出使用实例。 while循环 while循环是最简单的一种循环语句,其语法格式如下: while (条件判断)…

    C 2023年5月23日
    00
  • 一文搞懂C++中继承的概念与使用

    一文搞懂C++中继承的概念与使用 1. 继承的概念 继承是指在定义一个类时,可以在新的类中直接引用一个已有的父类的属性和行为,新的类称为子类或派生类,已有的类称为父类或基类。 子类会继承父类的公有成员和保护成员,但不会继承父类的私有成员。同时子类可以访问父类的公有成员和保护成员,但无法访问私有成员。 2. 继承的语法 继承语法如下所示: class Chil…

    C 2023年5月22日
    00
  • 首个 64 位 Windows 2000 系统的测试版本被发现

    首个 64 位 Windows 2000 系统的测试版本被发现攻略 背景介绍 Windows 2000是由微软公司发布的一款操作系统,它的核心采用了Windows NT技术,支持32位和64位处理器。此次发现的首个64位Windows 2000系统测试版本可以让人们更深入地了解Windows 2000的内部结构和设计。 攻略过程 寻找测试版本 首先,需要去寻…

    C 2023年5月23日
    00
  • 简单谈谈Python中的几种常见的数据类型

    下面是详细讲解“简单谈谈Python中的几种常见的数据类型”的完整攻略。 一、Python中的常见数据类型 Python是一种动态类型的解释性语言,因此在编程时可以不必预先定义变量类型。Python有许多不同的数据类型,其中一些常见的包括以下几种: 1. Numbers 类型 整数类型(int):即为整数,没有小数部分。例如:1,3,10等等。 # 示例1:…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部