我有一个值列表(1维),我想知道找到最接近查询值的最佳数据结构/算法。我在这里找到的大多数解决方案(全部?)是针对2个或更多维度的。任何人都可以向我建议我的方法吗?
我的直觉告诉我对数据进行排序并以某种方式使用二进制搜索。顺便说一下,对于所需的任何树的构造或插入时间没有限制,因此可能有人可以建议一个比排序列表更好的树。
答案 0 :(得分:9)
如果你需要比O(log(n))更快的东西,你可以使用排序数组或二叉搜索树轻松获得,你可以使用van Emde Boas Tree。 vEB树给你O(log(log(n)))来搜索两边最近的元素。
答案 1 :(得分:2)
如果插入时间无关紧要,则对排序数组进行二分查找是实现O(log N)查询时间的最简单方法。每次添加项目时都会对所有内容进行排序对于每个查询,执行二进制搜索。如果找到匹配项,请将其返回。否则,二进制搜索应该返回项目的索引,它应该被插入。使用此索引检查两个相邻项目,并确定哪些项目更接近查询点。
我认为有O(1)时间的解决方案。我将尝试考虑一个不涉及太多内存使用的问题......
答案 2 :(得分:1)
对列表进行排序并使用二进制搜索来查找您要查找的元素,然后比较左右邻居。您可以使用O(1)访问的数组。
类似的东西:
int nearest(int[] list, int element) {
sort(list);
int idx = binarySearch(element, list);
// make sure you are accessing elements that exist
min = (element - list[idx-1] <= list[idx+1] - element) ? idx-1 : idx+1;
return list[min];
}
这是O(n log n),如果要进行多次查找,将摊销。
编辑:为此您必须将此方法的排序移出
答案 3 :(得分:1)
正如您已经提到的,最快和最简单的方法应该是对数据进行排序,然后查找数据点的左右邻居。
答案 4 :(得分:0)
使用OCaml的Set
:
module S = Set.Make(struct type t = int let compare = compare end)
let nearest xs y =
let a, yisin, b = S.split y xs in
if yisin then y
else
let amax, bmin = S.max_elt a, S.min_elt b in
if abs (amax - y) < abs (bmin - y) then amax else bmin
顺便提一下,您可能会感谢nth-nearest neighbor sample和OCaml for Scientists文章 The F#.NET Journal 中的Traversing networks: nth-nearest neighbors。