.NET中的通用BinarySearch()
具有BinarySearch()
方法。 BinarySearch()
是一种用于搜索大型数据集的有效算法。我想我读过,如果世界上的每个人都被列入电话簿,那么二元搜索可以在35步内找到任何人。在List
上使用.Where
而不是将标准Where
子句与lambda一起使用时,应该在什么时候使用?在从BinarySearch
切换到Where
之前,数据集应该有多大?或{{1}}已在幕后使用二进制搜索?
答案 0 :(得分:3)
在{4}上使用
BinarySearch()
而不是使用带有lambda的标准Where
子句?
每当列表相对于您要搜索的值进行排序时,BinarySearch
将(平均)提供比Where
更好的性能,无论大小如何。
如果列表无序,或者订单与您正在寻找的值不符(您不能使用二进制搜索通过查找电话簿中的人第一个名称)然后BinarySearch
将无法为您提供正确的结果。
请注意,它只返回一个索引,而Where
会为您提供符合条件的所有项,但您可以在如果有重复项,则找到元素(BinarySearch
为您提供匹配的一个索引,而不一定是第一个索引。)
显然,列表越大,BinarySearch
给你的改善就越多。
Where
是否已在幕后使用二进制搜索?
否 - 它按物理顺序遍历列表。
答案 1 :(得分:3)
何时使用
List<T>.BinarySearch
?
您可以阅读documentation manual:
使用默认比较器在整个已排序的
List<T>
中搜索元素,并返回元素的从零开始的索引。
此外,它只能用于匹配给定的元素,而不是谓词,因为通用谓词会破坏订单约束。
因此必须通过默认比较器或给定的比较器对列表进行排序:
public int BinarySearch(T item) //default comparator
public int BinarySearch(T item, IComparer<T> comparer) //given comparator
算法在 O(log n)时间运行,而where
子句在 O(n)时间运行,这意味着在实践中它几乎会总是胜过第二个(除非很可能在列表的前面找到该元素)。
或者
.Where
是否已在幕后使用二进制搜索?
不,从那以后就不行了。 List<T>
并不总是排序。首先检查列表是否已排序,或者对列表进行排序需要分别计算 O(n)或 O(n log n)的计算量,这将是相同的甚至比线性搜索更昂贵。换句话说,首先检查列表是否已排序,然后 - 如果是这种情况 - 执行二进制搜索将比执行线性搜索更昂贵。线性搜索可以处理无序列表和谓词,但成本要高得多。