The original description of the k-d tree recognized that rebalancing techniques, such as are used to build an AVL tree or a red-black tree, are not applicable to a k-d tree. Hence, in order to build a balanced k-d tree, it is necessary to find the median of the data for each recursive subdivision of those data. The sort or selection that is used to find the median for each subdivision strongly influences the computational complexity of building a k-d tree. This paper discusses an alternative algorithm that builds a balanced k-d tree by presorting the data in each of k dimensions prior to building the tree. It then preserves the order of these k sorts during tree construction and thereby avoids the requirement for any further sorting. Moreover, this algorithm is amenable to parallel execution via multiple threads. Compared to an algorithm that finds the median for each recursive subdivision, this presorting algorithm has equivalent performance for four dimensions and better performance for three or fewer dimensions.
academic 论文ID : 1410.5420标题 : Building a Balanced k-d Tree in O(kn log n) Time作者 : Russell A. Brown分类 : cs.DS (Data Structures and Algorithms)发表时间 : 2014年10月 (arXiv预印本,最新版本2025年10月)论文链接 : https://arxiv.org/abs/1410.5420 k-d树的原始描述认识到,用于构建AVL树或红黑树的重新平衡技术不适用于k-d树。因此,为了构建平衡的k-d树,需要为数据的每次递归细分找到中位数。用于为每次细分找到中位数的排序或选择强烈影响构建k-d树的计算复杂度。本文讨论了一种替代算法,该算法通过在构建树之前在k个维度中的每个维度上预排序数据来构建平衡的k-d树。然后在树构建过程中保持这k个排序的顺序,从而避免了进一步排序的需要。此外,该算法适合通过多线程并行执行。与为每次递归细分找到中位数的算法相比,这种预排序算法在四维时具有等效性能,在三维或更少维度时具有更好的性能。
k-d树的重要性 : k-d树是Bentley在1975年引入的重要数据结构,用于存储k维数据,广泛应用于多维搜索、最近邻查找、范围查询等场景。平衡问题的挑战 : 与标准二叉树不同,k-d树在不同层级使用不同的键值进行划分,这使得传统的重新平衡技术(如AVL树或红黑树的旋转操作)不适用于k-d树。现有方法的局限性 :传统方法需要在每次递归细分时找到中位数 使用Quicksort找中位数:最好情况O(n),最坏情况O(n²) 使用Merge sort或Heap sort:保证O(n log n),但导致整体复杂度为O(n log² n) Blum等人的O(n)中位数算法虽然理论上优秀,但实现复杂 本文提出的预排序方法旨在:
避免在树构建过程中的重复排序操作 实现更好的渐近复杂度O(kn log n) 提供适合并行执行的算法设计 在低维度情况下获得更好的性能 提出了O(kn log n)复杂度的k-d树构建算法 :通过预排序避免递归过程中的重复排序设计了保持排序顺序的分区策略 :在树构建过程中维护k个预排序数组的有序性实现了高效的并行化方案 :算法天然适合多线程并行执行提供了全面的性能分析 :包括理论复杂度分析和实际性能测试开发了多项优化技术 :包括超键比较优化、延迟排序分区等六项优化策略输入 : n个k维数据点的集合
输出 : 平衡的k-d树,支持高效的多维搜索操作
约束 : 保持树的平衡性,避免重复数据点
算法首先对数据进行k次merge sort,分别使用超键:
x:y:z (x是最高位,y是中位,z是最低位) y:z:x (y是最高位,z是中位,x是最低位) z❌y (z是最高位,x是中位,y是最低位) 超键设计的意义 :
不仅按主要坐标排序,还考虑次要坐标 确保相同的元组在每个索引数组中形成连续的组 便于检测和移除重复元组 算法流程:
1. 选择当前维度的索引数组的中位数元素作为分割点
2. 将其他维度的索引数组按此分割点进行分区
3. 分区过程保持各数组内部的排序顺序
4. 递归处理左右子数组,循环使用不同维度
对于每个非当前维度的索引数组:
遍历数组中的每个元素 将其超键与中位数的超键比较 根据比较结果分配到左半部分或右半部分 等于中位数的元素被排除(存储在树节点中) 传统方法只比较单一坐标,本文使用超键确保:
完全相同的元组能够被正确识别 排序结果具有确定性 便于去重操作 关键创新在于分区过程中保持原有的排序顺序:
不需要重新排序 维持O(kn log n)的复杂度 支持高效的递归处理 通过巧妙的数组置换策略:
在每层递归中循环使用xyz、yzx、zxy索引数组 确保当前维度的索引数组总是已排序的 减少内存分配开销 规模 : 2¹⁸ ≤ n ≤ 2²⁴个随机生成的k维元组数据类型 : 32位和64位随机整数维度范围 : k = 2, 3, 4, 5, 6, 8测试环境 : 2.3 GHz Intel i7处理器(四核),3.2 GHz Intel i7处理器(六核)总执行时间 : 包括预排序、去重和树构建的总时间时间复杂度验证 : 通过n log₂(n)的线性拟合验证并行加速比 : 多线程性能相对于单线程的提升维度扩展性 : 不同维度下的性能表现O(n log n)算法 : 使用Blum等人的O(n)中位数查找算法基准实现 : 非优化版本的O(kn log n)算法优化版本 : 包含六项优化的改进算法编程语言 : Java(主要测试)和C++(优化版本)并行策略 : 基于递归层级的线程分配线程数限制 : 1-12个线程内存管理 : 使用临时数组和索引数组的高效管理O(kn log n)算法 : 相关系数r = 0.998,斜率m = 1.6×10⁻⁷O(n log n)算法 : 相关系数r = 0.9986,斜率m = 1.6×10⁻⁷两种算法的执行时间都与n log₂(n)呈良好的线性关系 在2²⁴个元组的测试中:
k=4时:两种算法性能相当 k<4时:O(kn log n)算法性能更优 k>4时:O(n log n)算法性能更优 O(kn log n)算法的执行时间斜率:18.07秒/维度 O(n log n)算法的执行时间斜率:0.55秒/维度 使用8线程在Intel四核i7处理器上:
相对于单线程约3倍的性能提升 性能模型拟合公式:t = ts + t1/q + mc(q-1) 预测最优线程数:约6个线程 六项优化技术的综合效果:
4维数据测试 : O(n log n)算法提升28%,O(kn log n)算法提升26%8维数据测试 : O(n log n)算法提升65%,O(kn log n)算法提升34%超键比较优化 : 避免循环开销并发合并排序 : 两线程并行合并并发分区 : 双向分区策略延迟排序 : 性能提升6-8%(理论预测)实验发现执行时间不遵循传统的Amdahl定律,而是:
其中mc项反映了缓存竞争的影响。
通过对执行时间求导,得到最优线程数:
k=4是两种算法性能的临界点,这为实际应用中算法选择提供了指导。
传统k-d树构建 : Bentley的原始算法和各种改进中位数查找算法 : Blum等人的线性时间算法并行k-d树构建 : 针对图形学和射线追踪的优化空间数据结构 : R树、四叉树等相关结构预排序策略 : 与传统的递归中位数查找不同超键设计 : 解决了重复元素处理问题并行化方案 : 提供了实用的多线程实现全面的性能分析 : 包括理论和实验两个层面算法有效性 : O(kn log n)算法在低维度情况下优于传统O(n log n)算法并行可扩展性 : 算法具有良好的并行性能,适合多核处理器实用价值 : 提供了完整的实现和优化策略理论贡献 : 建立了缓存竞争的性能模型维度限制 : 高维度情况下性能不如O(n log n)算法内存开销 : 需要k个索引数组,内存需求较大实现复杂度 : 算法实现相对复杂,需要仔细处理索引数组的管理线程数限制 : 并行策略限制线程数必须是2的幂高维优化 : 针对高维数据的算法改进内存优化 : 减少内存使用的策略GPU并行 : 利用GPU进行大规模并行处理动态k-d树 : 支持插入和删除操作的动态版本理论创新 : 预排序策略是构建k-d树的新思路实验充分 : 提供了全面的性能测试和分析实用价值 : 开源代码和详细的实现指导写作清晰 : 算法描述详细,图表丰富优化全面 : 提供了多层次的性能优化技术适用范围限制 : 仅在低维度情况下有优势复杂度常数 : 虽然渐近复杂度优秀,但常数因子可能较大内存需求 : k个索引数组的内存开销在高维时显著实现难度 : 相比传统方法,实现更加复杂学术贡献 : 为k-d树研究提供了新的算法思路实际应用 : 适用于计算几何、机器学习等领域开源价值 : 提供了高质量的开源实现教育意义 : 很好的算法设计和分析案例低维空间数据 : 2-4维的空间数据处理静态数据集 : 构建后很少修改的数据集多核环境 : 有多核处理器资源的场景性能敏感应用 : 对构建速度有较高要求的应用本文引用了21篇重要文献,涵盖了:
Bentley的k-d树原始论文 4 Blum等人的线性时间中位数算法 6 各种排序算法的经典文献 8,12,20 并行计算和性能建模的相关工作 2,10 最近邻搜索和反向最近邻的应用 7,13 总体评价 : 这是一篇高质量的算法论文,在k-d树构建领域提出了创新的预排序方法。论文理论分析严谨,实验设计完整,实用价值较高。虽然在高维情况下存在局限性,但为低维空间数据处理提供了有效的解决方案,对相关领域具有重要的参考价值。