我假设您有最小和最大的X和Y坐标?如果是这样,那么怎么样呢。
将我们的半径R、Xmax-Xmin X和Ymax-Ymin Y称为二维矩阵[X/R,Y/R]的双向链表。将每个点结构放在正确的链接列表上。
要查找需要交互的点,您只需要检查您的单元格以及您的8个邻居。
例如:如果X和Y各为100,而R为1,则在单元格[43,77]中的43.2、77.1处放置一个点。您将检查匹配项的单元格[42,76] [43,76] [44,76] [42,77] [43,77] [44,77] [42,78] [43,78] [44,78]。请注意,您自己的框中并非所有单元格都匹配(例如43.9、77.9在同一列表中但距离超过1个单位),您始终需要检查所有8个邻居。
当点移动时(听起来它们会移动?),您只需取消链接它们(使用双链接列表快速轻松)并在其新位置重新链接。移动任何一个点的时间复杂度为O(1)。将它们全部移动的时间复杂度为O(n)。
如果该数组大小给出了太多单元格,您可以使用相同的算法和可能相同的代码制作更大的单元格;只需准备好实际上靠近的候选点较少即可。例如,如果R=1且地图是百万倍的R乘以百万倍的R,则无法制作如此大的2D数组。最好让每个单元格宽1000个单位?只要密度低,之前的代码应该仍然适用:仅针对此单元格及其相邻的8个单元格中的其他点检查每个点。只需准备好更多的候选点未能在R内。
如果某些单元格将有很多点,每个单元格都有一个链接列表,也许该单元格应该有一个由X坐标索引的红黑树?即使在同一个单元格中,绝大多数其他单元格成员也会离得太远,因此只需从X-R到X+R遍历树。与其循环遍历所有点并深入每个点的树中,不妨通过迭代树来寻找R内的X坐标,如果/当您找到它们时计算距离。当您从低到高X遍历一个单元格的树时,在前R个条目中,您只需要检查左侧单元格的相邻树。
您还可以转向小于R的单元格。您将有更少的候选项未能足够接近。例如,对于R/2,您将检查25个链接列表而不是9个,但平均而言(如果随机分布),您将检查25/36的点数。这可能是一个小收益。