前一阵做实验 要用到R树 在网上找了好多代码 都不是很理想 不过最后在一篇博客上找到了一个很靠谱 而且简单易懂 清晰明了的代码 完成了R树的构建 我把原文的代码稍稍修饰了一下 并提取出我所需要的 即R树的构建 再加上我自己写的用R树查询KNN 已经调试过了 可以运行 代码如下
#include "stdafx.h"
#include "math.h"
#include <iostream>
#define Invalid_Rect(x) ((x).bound[0] > (x).bound[2])
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define Maxfill 3 //此处将叶子节点包含对象个数的最大值和R树分值的最大值都设为maxfill
#define Minfill (Maxfill/2) //如上的最小值
#define FALSE 0
#define TRUE 1
using namespace std;
//定义矩形框的四个界值
typedef struct RTreeMBR
{
float bound[4];
}RTreeMBR;
//定义R树结点分支的结构体
typedef struct RTreeBranch
{
RTreeMBR mbr;//分支所在的矩形框
struct RTreeNode* child;//分支指向的孩子结点
int leafchild; //若为叶子节点(即无孩子节点),存储对象(点)的ID。
}RTreeBranch;
//定义R树结点的结构体
typedef struct RTreeNode
{
int mbrcount;//结点矩形框的个数
int level;//结点的高度
RTreeBranch branch[Maxfill];//结点的分支
}RTreeNode;
//结点划分时的结构体
typedef struct RTreePartition
{
int partition[Maxfill+1];
int total;
int minfill;
int taken[Maxfill+1];//记录小矩形框是否被划分
int ncount[2]; //划分成两块的各自矩形框的个数
RTreeMBR cover[2];//划分成两块的各自总的矩形框覆盖
double area[2]; //划分成两块的各自面积
}RTreePartition;
//搜索R树时放入优先队列(堆)的结点的结构体
typedef struct Node
{
RTreeNode* RNode;
float data;
char type;
int ID;
}Node;
RTreeBranch BranchBuf[Maxfill+1];
int BranchCount;
RTreeMBR CoverSplit;
double CoverSplitArea;
RTreePartition Partition[1];
int length;
void RTreeSplitNode(RTreeNode *node, RTreeBranch br, RTreeNode **new_node);
//创建r-tree,初始化根
RTreeNode* RTreeCreate()
{
RTreeNode *root=new RTreeNode;
root->mbrcount=0;
root->level=0;
for (int i=0;i<Maxfill;i++)
{
root->branch[i].child=NULL;
}
return root;
}
//合并两个矩形框
RTreeMBR RTreeCombineRect( RTreeMBR rc1, RTreeMBR rc2 )
{
int i, j;
RTreeMBR new_rect;
for (i = 0; i < 2; i++)
{
new_rect.bound[i] = MIN(rc1.bound[i], rc2.bound[i]);
j = i + 2;
new_rect.bound[j] = MAX(rc1.bound[j], rc2.bound[j]);
}
return new_rect;
}
//求矩形框的面积
double RTreeRectSurfaceArea( RTreeMBR rc )
{
double sum = (double) 0;
sum=(rc.bound[2]-rc.bound[0])*(rc.bound[3]-rc.bound[1]);
return sum;
}
//初始化矩形框
void RTreeInitRect( RTreeMBR *rc)
{
int i;
for (i=0; i<4; i++)
rc->bound[i] = (double) 0;
}
//初始化一个分支的矩形框和孩子指针
static void _RTreeInitBranch( RTreeBranch &br )
{
RTreeInitRect(&br.mbr);
br.child = NULL;
}
//初始化一个r树结点的分支个数和层数以及分支
void RTreeInitNode( RTreeNode *node )
{
int i;
node->mbrcount = 0;
node->level = -1;
for (i = 0; i < Maxfill; i++)
_RTreeInitBranch(node->branch[i]);
}
//结点溢出时计算合并所有的矩形框
static void _RTreeGetBranches( RTreeNode *node, RTreeBranch br)
{
int i;
for (i=0;i<Maxfill;i++)
{
BranchBuf[i]=node->branch[i];
}
BranchBuf[Maxfill]=br;
BranchCount=Maxfill+1;
CoverSplit = BranchBuf[0].
RTree源代码-c语言实现
最新推荐文章于 2024-08-19 10:41:59 发布
本文介绍了一个C语言实现的RTree数据结构,包括R树的构建、插入和KNN查询。通过实例代码展示了如何创建R树、合并矩形框、计算矩形面积以及搜索最近邻等核心操作。
摘要由CSDN通过智能技术生成