何时使用List <t> .BinarySearch?

时间:2016-06-16 19:35:09

标签: c# .net algorithm search binary-search

.NET中的通用BinarySearch()具有BinarySearch()方法。 BinarySearch()是一种用于搜索大型数据集的有效算法。我想我读过,如果世界上的每个人都被列入电话簿,那么二元搜索可以在35步内找到任何人。在List上使用.Where而不是将标准Where子句与lambda一起使用时,应该在什么时候使用?在从BinarySearch切换到Where之前,数据集应该有多大?或{{1}}已在幕后使用二进制搜索?

2 个答案:

答案 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)的计算量,这将是相同的甚至比线性搜索更昂贵。换句话说,首先检查列表是否已排序,然后 - 如果是这种情况 - 执行二进制搜索将比执行线性搜索更昂贵。线性搜索可以处理无序列表和谓词,但成本要高得多。