It is best to add some auxiliary information. The common method is to divide the grid, assign all points to different grids, and then find the nearest point based on the grid. In this case, we need to add a grid structure (exchange space for time) to store the id of points belonging to this grid. We can quickly find the nearest grid, and then find the points inside through the numbering rules, which can improve the speed of finding points.
Hehe, sorry, I wrote it without thinking clearly: P, change it, change it, just add one more step.
1. Add grid information to this point:
Level a
{
Public int ID
public int X;
public int Y;
Publiciint index; //The grid number to which it belongs.
}
2. Construct a point linked list, which is added to reduce space and facilitate processing, and will be very useful in the following algorithms.
(Create a point linked list node for each point object)
class A
{
public a* pao object; //Point to a point object
Publci I * pNextA///points to the next one.
}
3. Component A grid information structure
Class g
{
Public int ID// grid number
Public I * object; //Point to a point linked list (whether it is a leader node or not)
//The linked list is better here.
//First, because points can be moved, the number of point objects can be arbitrary, which can give play to the expansibility of linked list.
//Second, you don't need to go through intermediate nodes, so you don't take advantage of arrays.
}
4. Establish a grid, such as a square grid, with the length of 1000 (the length can be defined by itself, and the key is to balance the relationship between space and speed), so (0,0) to (1000000, 100000 * 65400) is/kloc.
5. When adding a point, first determine which grid it belongs to, then add the grid number to the point information, and at the same time construct the corresponding point linked list node and add it to the linked list of the grid it belongs to.
6. Finally, the query point. First, get the grid information of the starting point to see if there are any other points in the grid: if there are, judge the distance (the square of the distance) one by one, then the nearest point must be among these points (if there are still too many points, consider narrowing the grid range); No, then find out if there are any dots in the eight grids around the grid. If there is, then find the nearest point, if not, then expand (if there are too many grids, you can increase the range of the grid).
7. According to the distance from the nearest point to the starting point, see how many grids the starting point and the surrounding grids will touch within this distance (there is no traversal in 6), and then look at the points in these grids to see if there are any closer ones.
note:
1. If the optimization is to increase the level of the grid, you can use a multi-layer grid, which will be more complicated.
2. In the grid information structure (G), because the points will move, there will be a search process for the nodes that delete the list. If this is slow, add a pointer to the point list in the point object structure:
One kind;
Level a
{
Public int ID
public int X;
public int Y;
Publiciint index; //The grid number to which it belongs.
publci I * pI
}
....
Hehe, after reading lipai006' s answer, it seems that you can achieve better speed as long as you spend more memory. In fact, you don't need to start from the X coordinate and slowly expand it into a fan. By making some auxiliary structures, we can directly start from the X coordinate of the starting point and find the Y coordinate which is different from X and closest to the starting point. The end condition of the cycle is that the expansion distance of x is already greater than the current minimum distance, because it must be greater than the current one. This method is to use more complex auxiliary structure to index and do more things when adding points. Moreover, the code in the implementation is more complicated than the grid method, but the search speed should be faster than the grid method, because after all, it is to find points directly. In fact, the grid method regards the x and y coordinates of a batch of points as the same, so that a batch is filtered first, which is a compromise between speed and complexity.
Xx_lzj: The purpose of dividing regions is to keep the number of points in each region from too much. According to my structure, it is enough to judge whether each region is a bit, and there will be nothing bool sparse to affect efficiency, but in the worst case, it will indeed degenerate to traverse the whole point space, so the time complexity of this method is still O(n).
In fact, your method is similar to the principle of lipai006 (if my guess of your linked list structure is accurate). It is nothing more than forming a two-dimensional linked list through x and y coordinates. The formation process of this linked list will be relatively more complicated than the grid, and it is not enough to judge 8 points as you think. When there is only one point in the middle and other points are distributed on the circle with this point as the center, are there only eight nearest points according to the owner's requirements? In this case, your worst complexity is O(n), but as I said, the average time complexity of this method in terms of parameters will be lower than that of the grid, but the code complexity of the algorithm itself will be higher, and the time consumption in the process of inserting points will be higher. I think this is a complete process, and we can't sacrifice too much other time for fast search.
*************
Xx_lzj: Sorry, there are still some things you don't understand in your linked list: 1. Each node of a two-dimensional linked list has four pointers. Can you tell me how to get to these four hands? It is best not to take a point on the boundary line, but to take a point in the middle to introduce it. 2. When initializing and modifying point coordinates, if the existing data is a linked list structure (not an array), how to find it in half without relying on other auxiliary data? 3. After modifying the coordinates of a point, according to your linked list structure, it feels not as simple as deleting or inserting a node. Can you explain it in detail