四叉树C++实现(增删改查,找邻居)

        好久好久没更过了,因为入坑了一本天书的缘故,有一些比较特别的数据结构需要学一下,第一个就是这个四叉树,工作占的时间太多了,只能用剩下的时间来学一学了,话不多说,先来介绍一下基本的概念:

        我们这里的四叉树指的是满四叉树,也就是每个节点要么有四个孩子节点,要么没有孩子节点,它在二维空间中可以表示对一个正方形进行四个象限的分割,从右上,左上,左下,右下这四个方向可以依次表示为第一象限,第二象限,第三象限和第四象限,如图:其中,根节点表示大的正方形,根节点下的四个节点分别表示对应的四个分割出来的正方形。

 

 

       这里,还有三个关于四叉树的定理:

 1.平面中一组点P的四叉树的深度最多为log(s/c) + 3/2,其中c是P中任意两个点之间的最小距离,s是正方形的边长。

 2.存储了一组n个点,深度为d的四叉树,具有O(d + 1)个结点并且可以在O((d+1)n)时间内构造。

 3.设T为深度为d的四叉树,如上所述,T中给定节点v在给定方向上的邻居可以在O(d+1)时间内找到。

      定理为啥成立,我也不知道,一本很阴间的书上写的。 定义和定理结束了,下面是代码,我用C++实现的:

      关于四叉树的类定义:(重载的运算符和构造函数,析构函数,拷贝构造函数方法体都放在类里了,自定义的函数方法体放在了类外)

      对于四叉树的每个节点,我定义它有一个矩形区域,有一个链表pointList表示在这个矩形区域内的点,以及四个指向孩子节点的指针和指向父节点的指针,还有一系列函数。书上虽然是按正方形讲的,但是,矩形好像更加准确,所以我下边都写的矩形。

      class QuadTree
{
    public:

        //四叉树对应的矩形区域。
        Rectangle treeRec;
        
        QuadTree(){}
        QuadTree(Rectangle treeRec){this->treeRec = treeRec;}
        QuadTree(Rectangle treeRec,PointList* pointList)
        {
            this->treeRec = treeRec;
            this->pointList = pointList; 
        }
        //对于用这个构造函数的形式创建的四叉树,是在矩形区域分裂得到子节点的时候用到的,因此,对于父节点矩形区域中的点链表(不带头节点),需要分给子节点。
        QuadTree(Rectangle treeRec,QuadTree* parent)
        {
            this->treeRec = treeRec;
            this->pointList = pointList; 
            this->parent = parent;
            
            PointList* parentList = parent->pointList;
            pointList = new PointList();
            Point p(-1,-1);
            pointList->point = p;
            //cout<<pointList->point.x <<endl; 
            pointList->next = NULL;
            while(parentList!=NULL)
            {
                if(treeRec.IsInRectangle(parentList->point))
                {
                    if(pointList->point.x == -1)
                    {
                        pointList->point = parentList->point;
                        //cout<<1<<endl;
                    }
                    else
                    {
                        pointList->Insert(parentList->point);
                    }
                }
                
                parentList = parentList->next;
            }
            
        }  
        ~QuadTree()
        {
            delete rightTopTree;
            delete leftTopTree;
            delete leftBottomTree;
            delete rightBottomTree;
            delete pointList;
            delete this;
        }
        
        QuadTree* rightTopTree;
        QuadTree* leftTopTree;
        QuadTree* leftBottomTree;
        QuadTree* rightBottomTree;
        
        QuadTree* parent;
        

        //这个表示一个点的链表,表示这个父节点的矩形区域中有这些点。
        PointList* pointList;
        

        //剩下的函数我会在代码中说明,读者读到这只需要根据它的名字明白它是干啥的就行了。
        void CreateChildren();
        
        Rectangle* RectangleSearch(Point point,Rectangle* rec,QuadTree* root);
        
        bool PointSearch(Point point);
        
        bool PointDelete(Point point,QuadTree* tar);
        
        bool RectangleDelete(Rectangle rec,QuadTree* tar);
        
        void DeleteAllChildren(QuadTree* tar);
        
        QuadTree* FindNeibor(Direction dir,QuadTree* tar,QuadTree* parent); 
        
};

 

 

下面是矩形和点,以及点链表的定义,没啥好说的:

class Point
{
    public:
        int x;
        int y;
        Point(const Point &point)
        {
            x = point.x;
            y = point.y;
        } 

        Point(int x,int y)
        {
            this->x = x;
            this->y = y;
        }
        Point()
        {
        } 
        ~Point(){}
        bool operator==(Point& other)
        {
             return this->x == other.x && this->y == other.y;
        }
    
        bool operator!=(Point& other)
        {
            return this->x != other.x || this->y != other.y;
        }
    
         Point operator=(Point& other)
        {
            this->x = other.x;
            this->y = other.y;
            return *this;
        }
        
};

class PointList

    public:
        Point point;
        PointList* next;
        void Insert(Point point);
        friend bool Delete(PointList*& tar, Point point);

        //Fix表示的是改
        void Fix(Point point,Point tar);
        bool Search(Point point);
            
};

class Rectangle
{
    public:
        int xMin;
        int xMax;
        int yMin;
        int yMax;
        Rectangle(int xMin,int xMax,int yMin,int yMax)
        {
            this->xMin = xMin;
            this->xMax = xMax;
            this->yMin = yMin;
            this->yMax = yMax;
        }
        
        bool operator==(const Rectangle& other)
        {
            return this->xMin == other.xMin && this->xMax == other.xMax && this->yMin == other.yMin && this->yMax == other.yMax;
        }
        
        bool operator!=(const Rectangle& other)
        {
            

  • 9
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
下面是一个简单的例子,演示了如何用C++实现增删改查: ```c++ #include <iostream> #include <string> #include <vector> using namespace std; struct Student { string name; int age; string gender; }; vector<Student> students; // 添加学生信息 void addStudent() { Student stu; cout << "请输入学生姓名:"; cin >> stu.name; cout << "请输入学生年龄:"; cin >> stu.age; cout << "请输入学生性别:"; cin >> stu.gender; students.push_back(stu); cout << "添加成功!" << endl; } // 删除学生信息 void deleteStudent() { string name; cout << "请输入要删除的学生姓名:"; cin >> name; for (auto it = students.begin(); it != students.end(); it++) { if (it->name == name) { students.erase(it); cout << "删除成功!" << endl; return; } } cout << "未到该学生信息!" << endl; } // 修改学生信息 void modifyStudent() { string name; cout << "请输入要修改的学生姓名:"; cin >> name; for (auto& stu : students) { if (stu.name == name) { cout << "请输入学生新姓名:"; cin >> stu.name; cout << "请输入学生新年龄:"; cin >> stu.age; cout << "请输入学生新性别:"; cin >> stu.gender; cout << "修改成功!" << endl; return; } } cout << "未到该学生信息!" << endl; } // 查询学生信息 void queryStudent() { string name; cout << "请输入要查询的学生姓名:"; cin >> name; for (auto& stu : students) { if (stu.name == name) { cout << "姓名:" << stu.name << endl; cout << "年龄:" << stu.age << endl; cout << "性别:" << stu.gender << endl; return; } } cout << "未到该学生信息!" << endl; } int main() { while (true) { cout << "请选择操作:1.添加 2.删除 3.修改 4.查询 5.退出" << endl; int choice; cin >> choice; switch (choice) { case 1: addStudent(); break; case 2: deleteStudent(); break; case 3: modifyStudent(); break; case 4: queryStudent(); break; case 5: return 0; default: cout << "输入错误,请重新选择!" << endl; } } return 0; } ``` 上面的代码使用了vector来存储学生信息,通过遍历vector来实现增删改查。其中,使用了结构体来表示学生信息。在添加、删除和修改时,通过遍历vector来查要操作的学生信息;在查询时,同样遍历vector,根据输入的姓名来查学生信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值