收款履行声明的澄清';从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)
)才能找到匹配的元素。