前言
如果有错欢迎指出 qwq
本文前置知识:主定理
kd-tree(KDT) 时间复杂度证明
kd-tree 是一种可以高效处理 k k k 维空间的数据结构
在算法竞赛类的题目中一般有 k = 2 k=2 k=2
还有个比较有趣的结论,当 k = 1 k=1 k=1 时其实它就是一棵线段树
下文中的 n n n 为kd-tree中的结点数量, k k k 为kd-tree的维度
一、建树
一般建树有三种
- 随机划分(玄学)
- 轮换划分:每个维度轮着划分
- 方差划分:优先划分方差较大的维度
我可不想分析玄学的划分
1. 轮换划分
显然有递推式 T ( n ) = 2 T ( n / 2 ) + O ( n ) T(n) = 2T(n/2) + O(n) T(n)=2T(n/2)+O(n)
根据主定理,有 a = 2 , b = 2 , log b a = 1 , f ( n ) = O ( n ) a=2,b=2,\log_b{a}=1,f(n)=O(n) a=2,b=2,logba=1,f(n)=O(n)
∵ ∃ ϵ ≥ 0 \because \exist \epsilon \ge 0 ∵∃ϵ≥0 使得 f ( n ) = Θ ( n log b a log ϵ n ) f(n) = \Theta(n^{\log_b{a}}\log^{\epsilon}n) f(n)=Θ(nlogbalogϵn) ,此时 ϵ = 0 \epsilon = 0 ϵ=0
∴ T ( n ) = Θ ( n log n ) \therefore T(n) = \Theta(n\log n) ∴T(n)=Θ(nlogn)
2. 方差划分
注意到 T ( n ) = 2 T ( n / 2 ) + O ( k n ) T(n) = 2T(n/2) + O(kn) T(n)=2T(n/2)+O(kn)
因此时间复杂度为 T ( n ) = Θ ( n k log n ) T(n) = \Theta(nk\log n) T(n)=Θ(nklogn)
一般在算法竞赛中,由于 k k k 很小(一般 k = 2 k=2 k=2 ),因此有
T ( n ) = Θ ( n log n ) T(n) = \Theta(n\log n) T(n)=Θ(nlogn)
本划分方法能较好保证树高,且不易被卡
二、插入&删除
一般采用替罪羊树的插入&删除操作
利用重构子树的方式维持平衡
均摊复杂度为 O ( log n ) O(\log n) O(logn)
证明可以去看替罪羊树的,这里先留个坑以后补上
三、Range Query
个人感觉算kd-tree的核心操作吧
支持将一个超长方体区域内的点划分为 O ( n ) O(\sqrt{n}) O(n) 个点所管辖的区域
称 R R R 为待查询的超长方体,则对于树上结点所管辖的超长方体分类,存在以下三种情况
-
与 R R R 的交集为空
-
全部包含于 R R R 内
-
与 R R R 有交集且不包含于 R R R
算法在查询过程中,碰到第1,2类点不会继续递归其子树
因此算法的时间复杂度就与第3类点的数量有关
我们以轮换划分来分析,则在相邻的 k k k 轮中,分别对每一维进行了划分
显然会产生 2 k 2^k 2k 个部分,每个部分的大小均为原来的 1 2 k \dfrac{1}{2^k} 2k1
由于一个用于划分的超平面至多跨越 2 k − 1 2^{k-1} 2k−1 个部分(可以由归纳法证明,此处略)
则有 T ( n ) = 2 k − 1 T ( n / 2 k ) + O ( 1 ) T(n) = 2^{k-1}T(n/2^k)+O(1) T(n)=2k−1T(n/2k)+O(1)
根据主定理,有 a = 2 k − 1 , b = 2 k , log b a = k − 1 k , f ( n ) = O ( 1 ) a=2^{k-1},b=2^k,\log_b{a} = \dfrac{k-1}{k},f(n)=O(1) a=2k−1,b=2k,logba=kk−1,f(n)=O(1)
∵ ∃ ϵ > 0 \because \exist \epsilon > 0 ∵∃ϵ>0 使得 f ( n ) = O ( n log b a − ϵ ) f(n) = O(n^{\log_b{a}-\epsilon}) f(n)=O(nlogba−ϵ) ,此时 ϵ = k − 1 k \epsilon = \dfrac{k-1}{k} ϵ=kk−1
∴ T ( n ) = Θ ( n 1 − 1 k ) \therefore T(n) = \Theta\left(n^{1-\frac{1}{k}}\right) ∴T(n)=Θ(n1−k1)
当 k = 2 k=2 k=2 时, T ( n ) = Θ ( n ) T(n) = \Theta(\sqrt{n}) T(n)=Θ(n)
总结
本文简单分析了一下kd-tree的时间复杂度
参考文献
[1] KDT小记
转载请说明出处