收款履行声明的澄清';从javadoc进行二进制搜索

收款履行声明的澄清';从javadoc进行二进制搜索,java,algorithm,list,collections,complexity-theory,Java,Algorithm,List,Collections,Complexity Theory,我对binarySearch的性能分析感到困惑 它说: 如果指定的列表未实现随机访问接口 这个方法将进行基于迭代器的二进制搜索 执行O(n)链路遍历和O(logn)元素比较 我不知道如何解释这个O(n)+O(logn) 我的意思是,这不是比简单地遍历链表并进行比较更糟糕吗?我们仍然只有O(n) 那么这句话对性能意味着什么呢?正如我所说,我无法理解链表中简单线性搜索的区别 我在这里误解了什么 首先,您必须了解,如果没有RandomAccess接口,binarySearch不能简单地访问列表中的随机

我对
binarySearch
的性能分析感到困惑

它说:

如果指定的列表未实现随机访问接口 这个方法将进行基于迭代器的二进制搜索 执行O(n)链路遍历和O(logn)元素比较

我不知道如何解释这个
O(n)
+
O(logn)

我的意思是,这不是比简单地遍历链表并进行比较更糟糕吗?我们仍然只有
O(n)

那么这句话对性能意味着什么呢?正如我所说,我无法理解链表中简单线性搜索的区别


我在这里误解了什么

首先,您必须了解,如果没有
RandomAccess
接口,
binarySearch
不能简单地访问列表中的随机元素,而是必须使用迭代器。这就引入了成本。当集合实现
随机访问时
,每个元素访问的成本是
O(1)
,就渐近复杂性而言,可以忽略

因为
O(n)
大于
O(logn)
它将始终优先于
O(logn)
,并控制复杂性。在这种情况下,
binarySearch
与简单线性搜索具有相同的复杂性那么优势是什么?


线性搜索执行
O(n)
比较,而不是
O(logn)
使用
binarySearch
进行比较,无需随机访问。当
O(logn)
之前的常数较高时,这一点尤为重要。简单地说:当单个比较与高级迭代器相比成本非常高时。这可能是非常常见的情况,因此限制比较的数量是有益的。利润

二进制搜索不适用于链表。该算法应该受益于随机访问的排序集合(如普通数组),它可以快速从一个元素跳到另一个元素,在每次迭代中将剩余的搜索空间分成两个(因此时间复杂度为
O(logn)

对于链表,有一个修改过的版本,它迭代所有元素(在最坏的情况下需要遍历
2n
元素),但它不是比较每个元素,而是只在指定位置“探测”列表(因此,与线性搜索相比,进行比较的次数较少)


由于比较通常比普通指针迭代的成本稍高,所以总时间应该更低。这就是为什么要分别强调
logn
部分。

这里的关键是总运行时间并不是真正的
O(N)+O(logn)
,因为两个大O表示不同的操作。实际上是
O(n)*(遍历链接的时间)+O(logn)*(比较两个元素的时间)
。所以区分这一点很重要。@tskuzzy:对,但从技术上讲,对于足够大的
n
,时间是
O(n)
,无论比较两个元素的
时间与遍历链接的
时间相比有多大。与线性搜索相比,比较慢的优点显而易见。@TomaszNurkiewicz:对于遍历,我们只更新一个指针,这不重要吗?例如,
常量操作
?@user384706:是的,将迭代器向前推进一次是
O(1)
,但必须执行几次(因此
O(n)
)才能找到匹配的元素。