为什么有List <t> .BinarySearch(...)?</t>

时间:2010-07-15 13:40:44

标签: c# list collections binary-search

我正在查看List,我看到一个带有一些重载的BinarySearch方法,我不禁想知道在List中有这样的方法是否有意义?

除非对列表进行排序,否则为什么要进行二进制搜索?如果列表没有排序,调用该方法只会浪费CPU时间。在List上使用该方法有什么意义?

9 个答案:

答案 0 :(得分:22)

我注意到除了其他正确答案之外,二进制搜索难以正确编写。有很多极端情况和一些棘手的整数运算。由于二进制搜索显然是对排序列表的常见操作,因此BCL团队通过正确一次编写二进制搜索算法,而不是鼓励客户编写自己的二进制搜索算法,从而为世界提供服务;这些客户撰写的大量算法都是错误的。

答案 1 :(得分:17)

排序和搜索是列表上两种非常常见的操作。通过不在常规列表中提供二进制搜索来限制开发人员的选项是不友好的。

库设计需要妥协 - .NET设计人员选择在两个阵列上提供二进制搜索功能和C#中的列表,因为他们可能觉得(就像我这样)这些是有用和常见的操作,以及选择使用它们的程序员在调用它们之前了解它们的先决条件(即列表已被命令)。

使用Sort()重载之一对List<T>进行排序很容易。如果您觉得需要一个gaurantees排序的不变量,您可以随时使用SortedList<TKey,TValue>SortedSet<T>

答案 2 :(得分:6)

BinarySearch仅对已排序的List<T>有意义,就像IList<T>.Add仅对IList<T> IsReadOnly = false有意义一样。这很麻烦,但它只是需要处理的事情:有时功能X依赖于标准Y.Y并不总是正确的事实并不会使X变得无用。

现在,在我的意见中,令人沮丧的是,.NET没有的通用 SortBinarySearch方法 IList<T>实现(例如,作为扩展方法)。如果是这样,我们可以轻松地对进行排序,以便在任何非只读集合中搜索提供随机访问的项目。

然后,您可以随时编写自己的(或copy someone else's)。

答案 3 :(得分:5)

其他人指出BinarySearch对排序List<T>非常有用。但它并不真正属于List<T>,因为任何具有C ++ STL经验的人都会立即认出来。

随着最近的C#语言的发展,定义排序列表的概念(例如,ISortedList<T> : IList<T>)和定义BinarySearch(等人)作为该接口的扩展方法更有意义。这是一种更清洁,更正交的设计。

我已经开始将其作为Nito.Linq库的一部分。我预计第一个稳定版本会在几个月内发布。

答案 4 :(得分:2)

是,但List也有Sort()方法,所以你可以在BinarySearch之前调用它。

答案 5 :(得分:1)

我同意在未排序的列表上调用BinarySearch是完全愚蠢的,但如果您知道您的大型列表已排序,则它是完美的。

我在检查流中的项目是否存在于(或多或少)100,000个或更多项目的静态列表中时使用过它。

二进制搜索列表的ORDERS比执行list更快。找到,比数据库查找快几个数量级。

我有道理,我很高兴(如果不是这样的话,那就不是火箭科学的实施)。

答案 6 :(得分:1)

搜索和排序是算法原语。标准库具有快速可靠的实现是有帮助的。否则,开发人员会浪费时间重新发明轮子。

然而,就.NET Framework而言,遗憾的是,算法的具体选择恰好使它们的有用性降低。在某些情况下,他们的行为没有定义:

  1. List<T>.BinarySearch如果List包含多个具有相同值的元素,则该方法仅返回其中一个匹配项,并且可能返回任何一个匹配项,不一定是第一个一个

  2. List<T>此实现执行不稳定的排序;也就是说,如果两个元素相等,可能不会保留它们的顺序。相反,稳定的排序保留了相等元素的顺序。

  3. 这是一种耻辱,因为确实性算法同样快,而且这些算法作为构建块更有用。值得注意的是,Python,Ruby和Go中的二进制搜索算法都找到了第一个匹配元素。

答案 7 :(得分:1)

也许另一点是数组可以同样未排序。所以理论上,在阵列上使用BinarySearch也可能是无效的。

但是,与更高级别语言的所有功能一样,它们需要由有理由和理解数据的人应用,否则它们将失败。当然,可以应用一些交叉检查,我们可以有一个标志,表示&#34; IsSorted&#34;否则它会在二进制搜索上失败,但是......

答案 8 :(得分:0)

一些伪代码:

if List is sorted
   use the BinarySearch method
else if List is not sorted and you think sorting it is "waste of CPU time"
   use a different algorithm that is more suitable and efficient