四叉树,C++语言实现,并支持测试点是否在矩形内,前端使用Qt展示效果

首先放图:

可以添加测试矩形,可以自定义添加点,点击测试按钮,可以判断点是否在矩形内,通过四叉树数据结构实现上述功能。

本人V:860472025,有任何Qt、C++开发问题可以联系我,不免费哦,但价格很低!!

template<typename T>
struct Point {
	T x;
	T y;
	Point() {}
	Point(T _x, T _y) :x(_x), y(_y) {}
};

template<typename T>
struct Node {
	Node* R[4];					// 存储四个子节点的指针
	Point<T> pt;				// 存储点坐标
	Node* parent;				// 存储父节点的指针
};

template<typename ElemType>
class QuardTree
{
public:
	QuardTree();
	~QuardTree();
	void Insert(const Point<ElemType>& pos);				// 插入节点
	void BalanceInsert(const Point<ElemType>& pos);			// 平衡插入节点
	int nodeCount();										// 获取节点数
	int TPLS();												// 获取树的深度
	int Height();											// 获取树的高度
	void RegionResearch(ElemType left, ElemType right, ElemType botom, ElemType top, int& visitednum, int& foundnum);			// 区域搜索
	void clear();											// 清除所有节点
	vector<Point<ElemType>> m_FinedPoint;
private:
	Node<ElemType>* root;									// 根节点指针
	int Compare(const Node<ElemType>* node, const Point<ElemType>& pos);				// 比较节点位置
	bool In_Region(Point<ElemType> t, ElemType left, ElemType right, ElemType botom, ElemType top);			// 检查点是否在区域内
	bool Rectangle_Overlapse_Region(ElemType L, ElemType R, ElemType B, ElemType T, ElemType left, ElemType right, ElemType botom, ElemType top);   // 检查矩形是否重叠
	void RegionResearch(Node<ElemType>* t, ElemType left, ElemType right, ElemType botom, ElemType top, int& visitednum, int& foundnum);			// 递归区域搜索
	int Depth(Node<ElemType>*&); // 计算节点深度
	int nodeCount(const Node<ElemType>*);			// 计算节点数
	void clear(Node < ElemType>*& p);				// 递归清除节点
	void Insert(Node<ElemType>*&, const Point<ElemType>& pos);//递归插入节点
};


template<typename T>
QuardTree<T>::QuardTree()
{
	root = NULL;			// 初始化根节点为空
}

template<typename T>
QuardTree<T>::~QuardTree()
{
	clear(root);
}

template<typename T>
int QuardTree<T>::TPLS()
{
	return Depth(root);
}

template<typename T>
int QuardTree<T>::Compare(const Node<T>* node, const Point<T>& pos)
{
	if (pos.x == node->pt.x && pos.y == node->pt.y) return 0;  // 节点位置相同
	if (pos.x >= node->pt.x && pos.y > node->pt.y)  return 1;  // 节点在第一象限
	if (pos.x < node->pt.x && pos.y >= node->pt.y) return 2;  // 节点在第二象限
	if (pos.x <= node->pt.x && pos.y < node->pt.y)  return 3;  // 节点在第三象限
	if (pos.x > node->pt.x && pos.y <= node->pt.y) return 4;  // 节点在第四象限
	return -1;  // 不可能的情况
}


template<typename T>
void QuardTree<T>::BalanceInsert(const Point<T>& pos)
{
	Node<T>* node = (Node<T>*)malloc(sizeof(Node<T>));  // 分配新节点内存
	node->R[0] = NULL;
	node->R[1] = NULL;
	node->R[2] = NULL;
	node->R[3] = NULL;
	node->parent = NULL;
	node->pt = pos;  // 设置新节点位置
	if (root == NULL) {
		root = node;  // 如果根节点为空,将新节点设为根节点
		return;
	}
	Node<T>* temp = root;
	int direction = Compare(temp, pos);
	if (direction == 0) return;  // 节点已存在
	while (temp->R[direction - 1] != NULL) {
		temp = temp->R[direction - 1];  // 找到插入位置
		direction = Compare(temp, pos);
		if (direction == 0) return;  // 节点已存在
	}
	temp->R[direction - 1] = node;
	node->parent = temp;  // 插入新节点

	Node<T>* tp = temp->parent;
	if (tp == NULL) return;
	int r = Compare(tp, temp->pt);

	if (abs(direction - r) == 2) {
		Node<T>* leaf = node;
		if (tp->R[abs(3 - r)] == NULL) {
			tp->R[r - 1] = NULL;
			temp->parent = leaf;
			leaf->R[r - 1] = temp;

			temp->R[abs(3 - r)] = NULL;
			Node<T>* Rt = tp->parent;
			if (Rt == NULL) {
				root = leaf;
				leaf->parent = NULL;

				leaf->R[abs(3 - r)] = tp;
				tp->parent = leaf;
				return;
			}
			tp->parent = NULL;
			int dd = Compare(Rt, tp->pt);

			Rt->R[dd - 1] = leaf;
			leaf->parent = Rt;

			leaf->R[abs(3 - r)] = tp;
			tp->parent = leaf;
		}
	}
}


template<typename T>
void QuardTree<T>::Insert(Node<T>*& p, const Point<T>& pos)
{
	if (p == NULL)
	{
		Node<T>* node = (Node<T>*)malloc(sizeof(Node<T>));			// 分配新节点内存
		node->R[0] = NULL;
		node->R[1] = NULL;
		node->R[2] = NULL;
		node->R[3] = NULL;
		node->pt = pos;
		p = node;
		return;
	}
	else
	{
		int d = Compare(p, pos);
		if (d == 0) return;
		Insert(p->R[d - 1], pos);
	}
}


template<typename T>
void QuardTree<T>::Insert(const Point<T>& pos)
{
	int direction, len = 0;
	Node<T>* node = (Node<T>*)malloc(sizeof(Node<T>));				 // 分配新节点内存
	node->R[0] = NULL;
	node->R[1] = NULL;
	node->R[2] = NULL;
	node->R[3] = NULL;
	node->pt = pos;												// 插入新节点
	if (root == NULL)
	{
		root = node;
		return;
	}
	direction = Compare(root, pos);
	Node<T>* temp = root;
	if (direction == 0) return;//节点已存在 
	len = 1;
	while (temp->R[direction - 1] != NULL)
	{
		temp = temp->R[direction - 1];				// 找到插入位置
		direction = Compare(temp, pos);
		if (direction == 0) return;				// 节点已存在
	}
	temp->R[direction - 1] = node;				// 插入新节点
	//Insert(root, pos);//递归插入节点
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值