Here are some strange links to be interested in looking at:
Https://blog.sengxian.com/algorithms/k-dimensional-tree
http://zgjkt.blog.uoj.ac/blog/1693
Https://en.wikipedia.org/wiki/K-d_tree
Http://homes.ieu.edu.tr/hakcan/projects/kdtree/kdTree.html
K-d tree is a thing that divides a plane (or hyper plane) ...
For example, a one-dimensional case is dividing a axis, then it becomes our beloved two-fork search tree.
Two-dimensional situation
Use horizontal and vertical lines to divide a rectangle into two halves at a time.
There are three-dimensional, four-dimensional, and so on .... K-dimensional is called k-d tree.
This article is about the two-dimensional k-d tree.
Every time we have a point on the k-d tree, we have to cut along a certain axis, so how is this axis determined? A cut x-axis point of the child to cut the y-axis, cut the y-axis point of the child to cut the x-axis, take turns slicing, this is relatively good, and better write.
For example, this point is tangent to the x-axis, in order to query the harmony, then its left sub-tree all points to X is smaller than it, the right subtree all points to x larger than it (of course, can be equal to), this is consistent with the two-fork search tree.
① Achievements
For example, I now have n points, now to build a beautiful k-d tree, how to build it?
In BST we generally choose to compare the middle of a number, and then recursively go down to the achievement.
K-d tree is similar, but we want to make sure that the current node of the left subtree of the current dimension is smaller than it, the right sub-tree point current dimension is larger than it. Can we sort the current dimension at the current level each time and then select the median?
Notice that we just let the left side is relatively small, the right side is larger, the middle of the comparison between the line, sort a little bit of a waste, to the next dimension and again sort. Here we use the Nth_element function in STL, which internally uses the Quick_select algorithm (the first half of the fast sort) to do this, the complexity O (n).
void Nth_element (first,nth,last[,cmp]) (comparison function optional)
The elements of [first,last] are re-arranged so that the elements of the nth should be in the position after the sort, and the preceding elements are not greater than it, and the elements behind it are not less than
So we can build a more balanced k-d tree. The complexity of the reference line tree build-up proves it is easy to see that this thing is also O (NLOGN).
② Insertion
Well, it doesn't seem necessary to say that, that is, compare the current dimension with the current point and insert it.
For a more balanced k-d tree, the insertion is obviously O (Logn).
③ Inquiry
The first thing we need to solve is ... k-d tree has eggs?
Obviously k-d tree can be regarded as a more severe k-dimensional (this is the two-dimensional) line segment trees! You can play tag on this, you can ask (notice when you divide the rectangle), and even make segment tree beats (see Kat Driver's Training team thesis)
But in two-dimensional case, k-d tree is not very useful for segment trees ... Because there are two-dimensional tree array/two-dimensional line tree, after the CDQ division, the whole dichotomy of what ... Unless the subject is insane and the card space is online.
The normal k-d tree is used to ask the nearest point of the weapon!
For example, there is a problem (bzoj2648) that asks each time to ask for a dot nearest to a given point (Manhattan distance) and add a black dot.
What a conscientious man!
We can do this when we look for it, we first set up ans as an inf, and then we start the recursive query from the root node.
For a node on the k-d tree, first update the answer with this point. Then for its two children, prioritize a rectangle close to the current point (note that the value is obviously not necessarily available) to update the answer recursively, and then update the answer if the rectangle distance to the other son is smaller than the answer, the answer is also updated with the other son.
For a more balanced k-d tree, the complexity of the query is the worst of O (sqrt (n)), which is usually O (log (n)).
(This "general" nature is similar to the SPFA so-called O (ke))
It is noted that the "near" distance between the Euclidean distance and the Manhattan distance can be used.
As for the K near Point pair is also relatively simple, we maintain a large heap, each time compare heap top what on the line.
This is obviously more complicated than just one klogk.
④ some small problems
Have you noticed that there are a number of "more balanced" words in the complexity of the moment?
Yes, the nature of the k-d tree is similar to a two-fork search tree without rotation.
If the tree is no longer inserted, then k-d tree is very balanced and can guarantee all the complexity of the query.
If the tree is still inserted or not directly inserted, then the k-d tree is still "very balanced" for random data, and the arbitrary construction of a data (such as the 2,2 3,3 ... such data) can be successfully stuck to k-d tree.
So if there are insertions and questions, you can only pretend that the data is random ...
Let's write it here today ... The code has time to fill it up (although I'm not sure when it will be filled in)
K-d Tree Learning notes