当前位置: 首页 > news >正文

Qt C++实现KD树


一、什么是KD树?
1、KD树(K-Dimension Tree)是一种对K维空间中的实例点进行存储,以便对其进行快速检索的树形数据结构。


2、KD树是一种二叉树,表示对K维空间的一个划分,构造KD树相当于不断地用垂直于坐标轴的超平面将K维空间切分,构成一系列的K维超矩形区域,KD树的每个结点对应于一个K维超巨型区域。


3、采用中位数切分超平面,确保左右子树数据量平衡,实例点存储在切分超平面上对应的结点,左右子结点都是左小右大。

4、利用KD树可以省去对大部分数据点的搜索(通过超球面相交判断实现剪枝),从而减少搜索的计算量。

5、构建时间复杂度O(n log n),查询平均时间复杂度O(log n)。



二、实例代码: 
用Qt C++实现,对于struct {double a; double b; double c;}类型的元素,输入键a和键b,想要查找最接近键a和键b对应的c。

//kdtree.h
#ifndef KDTREE_H
#define KDTREE_H#include <QVector>
#include <memory>struct DataPoint {double a;double b;double c;
};class KDNode {
public:DataPoint point;std::unique_ptr<KDNode> left;std::unique_ptr<KDNode> right;int axis;KDNode(const DataPoint& p, int ax) : point(p), axis(ax) {}
};class KDTree {
public:void build(const QVector<DataPoint>& points);double findNearestValue(double targetA, double targetB);void clear(); bool isEmpty() const;private:std::unique_ptr<KDNode> root;std::unique_ptr<KDNode> buildRecursive(QVector<DataPoint>::iterator begin,QVector<DataPoint>::iterator end,int depth);void nearestSearch(KDNode* node, const DataPoint& target,DataPoint& best, double& bestDist) const;double distance(const DataPoint& p1, const DataPoint& p2) const;
};
#endif // KDTREE_H//kdtree.cpp
#include "kdtree.h"
#include <algorithm>
#include <cmath>
#include <limits>void KDTree::build(const QVector<DataPoint>& points) {auto copy = points;root = buildRecursive(copy.begin(), copy.end(), 0);
}std::unique_ptr<KDNode> KDTree::buildRecursive(QVector<DataPoint>::iterator begin,QVector<DataPoint>::iterator end,int depth) {if (begin == end) return nullptr;int axis = depth % 2;int len = std::distance(begin, end);auto mid = begin + len / 2;std::nth_element(begin, mid, end, [axis](const DataPoint& p1, const DataPoint& p2) {return axis == 0 ? p1.a < p2.a : p1.b < p2.b;});auto node = std::make_unique<KDNode>(*mid, axis);node->left = buildRecursive(begin, mid, depth + 1);node->right = buildRecursive(mid + 1, end, depth + 1);return node;
}double KDTree::findNearestValue(double targetA, double targetB) {DataPoint target{targetA, targetB, 0};DataPoint best;double bestDist = std::numeric_limits<double>::max();nearestSearch(root.get(), target, best, bestDist);return best.c;
}void KDTree::clear() {root.reset(); 
}bool KDTree::isEmpty() const {return root == nullptr; 
}void KDTree::nearestSearch(KDNode* node, const DataPoint& target,DataPoint& best, double& bestDist) const {if (!node) return;double dist = distance(node->point, target);if (dist < bestDist) {bestDist = dist;best = node->point;}double diff = node->axis == 0 ? target.a - node->point.a : target.b - node->point.b;KDNode* near = diff <= 0 ? node->left.get() : node->right.get();KDNode* far = diff <= 0 ? node->right.get() : node->left.get();nearestSearch(near, target, best, bestDist);if (fabs(diff) < bestDist) {nearestSearch(far, target, best, bestDist);}
}double KDTree::distance(const DataPoint& p1, const DataPoint& p2) const {return std::hypot(p1.a - p2.a, p1.b - p2.b);
}

http://www.dtcms.com/a/308274.html

相关文章:

  • BH1750模块
  • 上证50期权2400是什么意思?
  • 常见中间件漏洞
  • 腾讯云edge
  • 【SpringMVC】拦截器,实现小型登录验证
  • 对于前端工程化的理解
  • 仓库管理系统-9-前端之Main主要区域的新增表单
  • 用AI一键生成可交互知识图谱:Knowledge Graph Generator 让信息可视化触手可及
  • 星云能量传送特效技术详解
  • 智能文本抽取技术:精准识别、定位并提取出关键信息
  • 05-netty基础-ByteBuf数据结构
  • cuda编程笔记(11)--学习cuBLAS的简单使用
  • 机械学习--逻辑回归
  • React组件化的封装
  • 内核寄存器操作mcu进入低功耗模式
  • Java 17 新特性解析与代码示例
  • JavaScript函数性能优化秘籍:基于V8引擎优化
  • YOLO+Pyqt一键打包成exe(可视化,以v5为例)
  • tomcat隐藏400报错信息
  • Augment Code与Cursor功能对比分析
  • BR/EDR PHY帧结构及其具体内容
  • Java高级用法之回调函数
  • PHP 核心特性全解析:从实战技巧到高级应用(2)
  • 财税企业经营管理秘籍(二):陌拜怎么做?
  • [Broken IOS] 配置CLI | 终端用户界面TUI
  • 如何利用 rowid 在OceanBase 中处理大表时提效
  • 【赵渝强老师】OceanBase租户的资源管理
  • TransportClient详细说一说
  • UI测试平台TestComplete如何实现从Git到Jenkins的持续测试
  • Odoo:免费开源的医疗器械行业解决方案