Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么会有一个列表<;T>;。二进制搜索(…)?_C#_List_Collections_Binary Search - Fatal编程技术网

C# 为什么会有一个列表<;T>;。二进制搜索(…)?

C# 为什么会有一个列表<;T>;。二进制搜索(…)?,c#,list,collections,binary-search,C#,List,Collections,Binary Search,我正在查看列表,看到一个带有一些重载的BinarySearch方法,我不禁想知道在列表中使用这样的方法是否有意义 为什么我要进行二进制搜索,除非列表已排序?如果列表没有排序,调用该方法只会浪费CPU时间。将该方法放在列表上有什么意义?是的,但是列表也有Sort()方法,因此您可以在二进制搜索之前调用它。排序和搜索是列表上两种非常常见的操作。不在常规列表上提供二进制搜索来限制开发人员的选择是不友好的。 库设计需要折衷-在C#中,.NET设计人员选择在数组和列表上提供二进制搜索功能,因为他们(和我一

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


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

是的,但是列表也有Sort()方法,因此您可以在二进制搜索之前调用它。

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

库设计需要折衷-在C#中,.NET设计人员选择在数组和列表上提供二进制搜索功能,因为他们(和我一样)可能觉得这些是有用的常见操作,而选择使用它们的程序员在调用它们之前理解它们的先决条件(即列表是有序的)


使用其中一个重载对
列表进行排序非常简单。如果您觉得需要一个Gaurantes排序的不变量,您可以始终使用or来代替。

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

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

二进制搜索列表比执行列表查找快几个数量级,查找比数据库查找快很多数量级


我说的很有道理,我也很高兴能做到这一点(如果不是这样的话,实现它就不是火箭科学了)。

其他人指出,
BinarySearch
在排序的
列表上非常有用。但它并不真正属于List,因为C++的STL经验的任何人都会立即认识到。
随着最近C语言的发展,定义排序列表的概念(例如,
ISortedList:IList
)和定义
BinarySearch
(等)作为该接口的扩展方法更有意义。这是一种更干净、更正交的设计


作为图书馆的一部分,我已经开始这样做了。我预计第一个稳定版本将在几个月后发布。

BinarySearch
仅在排序的
列表上有意义,就像
IList一样。Add
仅在
IsReadOnly=false的
IList
中有意义。这很混乱,但这只是需要处理的事情:有时功能X依赖于标准Y。Y不总是真的这一事实并不意味着X毫无用处

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


同样,你也可以写你自己的(或)。

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

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

然而,在.NET Framework的情况下,不幸的是,算法的特定选择恰好使它们没有可能有用。在某些情况下,他们的行为没有定义:

  • List.BinarySearch
    如果列表包含多个具有相同值的元素,则该方法仅返回一个实例,并且可能返回任何一个实例,不一定是第一个

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


  • 这是一个遗憾,因为有一些确定性算法同样快,而且它们会比构建块更有用。值得注意的是,Python、Ruby和Go中的二进制搜索算法都会找到第一个匹配的元素。

    也许还有一点是,数组可以同样不排序。因此,理论上,在数组上进行二进制搜索也可能是无效的

    然而,与高级语言的所有特性一样,它们需要由有理由和理解数据的人应用,否则它们将失败。当然,可以应用一些交叉检查,我们可以有一个写着“IsSorted”的标志,否则它将在二进制搜索中失败,但是

    一些伪代码:

    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
    

    即使是伟大的库设计者也会弄错:@Ron Warholic:一个特定的实现仅限于包含大约20亿个元素的列表,这一事实通常被描述为一种限制,而不是一个bug。我倾向于认为,即使一个人可以拥有一个包含超过20亿个元素的单片数据结构,也不意味着他应该这样做。这里有一个例子可以说明BinarySearch()的用途:将新元素添加到排序列表中,使其保持排序。但是
    BinarySearch
    方法已经在
    Array
    类中作为
    static
    方法公开了,我发现它更有意义。然而,对于一个集合来说,一个没有保证的实例方法听起来是不必要的