今天(18.5.4)室友A突然问我算法怎么入门,兴奋之下给他安利了邓公的《数据结构》,然而他接着又问我能不能两周内快速入门,毕竟打算搞Machine Learning,然后掏出手机看了下他老师给的安排:python学习并实现K近邻算法/决策树/朴素XXX/支持向量机(???),两周内,四选一
原来是以为我学的算法是差不多这样的才来请教,我懂个π啊
不过说回来10个月前我还是摸了一把KD树,K近邻什么的我应该还记得,特写此文回忆一下并督促自己做题更新
//以下文本均无代码实现
//以后会更新补上 //吧K近邻依靠的数据结构:KD树
简单的说就是扩展的K维度的二叉树,树中每个节点既代表一个实际的点又代表一个切割空间的超平面,那么我们需要直到它是具体怎么表达空间的
具体的实现要点
在KD树中,每一层节点的比较都是单独对某一维度作为key来比较,小则往左子树走,大则往右子树走.ACM中,为了省事,对于维度选择是每一层就直接更新到下一个维度比较,往复循环,比如\(K=3\)时就是\(x→y→z→x\)的遍历方法
别忘了KD树中的节点是要记录当前实际的点的,为了平衡我们选择的点是当前子树未划分空间存在的点的中值(按当前维度比较)
常见操作
①插入:像普通BST那样,只是比较过程变成了不断变换的\(K\)个维度,每次只比较一个维度
②查询:如果是查询\(P\)的最近点,从根开始,设\(ans\)为\(INF\),比较左右子树的距离大小,先往小的\(dfs\),递归完再搜大的一侧(前提是\(dis\)比当前\(ans\)更优),就是说如果与所作的圆没有交点则剪枝不再递归(曼哈顿距离的话就是矩形最小边距).\(K\)近邻的话再维护一个\(size\)为\(K\)的大根堆即可
③删除:(不存在的)打标记维护
维护
还没有接触到什么题型,点太多容易把树建歪就控制平衡因子偶尔暴力重构
目前来看似乎确实是个非常简单的\(DSA\)
但还可以实现 范围计数/合并/可持久化 剩下的边做题边补 习题:BZOJ 3815/3489/3065