【问题标题】:Big-O notation for LinkedList and BinarySearch [duplicate]链表和二分搜索的大 O 表示法 [重复]
【发布时间】:2014-09-21 17:52:11
【问题描述】:

我正在尝试计算此代码的 Big-Oh,它用于对链表执行二进制搜索:

public int search( List<T> list, T target ) {

        int low = 0;
        int high = list.size() - 1;
        int middle;

        while ( low <= high ) {             // frequency << log( n )
            middle = ( low + high ) / 2;
            int cmp = target.compareTo( list.get( middle ) );   // time << n

            if ( cmp < 0 ) high = middle - 1;
            else if ( cmp > 0 ) low = middle + 1;
            else return middle;

        }   // time << n log( n )

        return -1;

}   // time << n log( n )

我得到 O(n log(n)) 作为答案。这是计算这种类型列表的这种搜索方法的正确方法吗?

【问题讨论】:

  • 二分查找是 log n,而不是 n log n。查看此重复:stackoverflow.com/a/8185382/150818
  • @SaketJha:不,您假设按索引访问列表操作是 O(1),这不适用于链表。
  • @SaketJha,如果你正确阅读了这个问题,它会在链表上显示二进制搜索。那不是 O(log n)
  • 基本上,在链表上使用二分搜索是个坏主意……最好进行线性扫描,即 O(n)。
  • 我知道这不是最好的事情,但这是我们分析不同算法的任务。根据我的理解,LinkedList 的 get() 是 O(n),所以我认为 n*log(n) 是正确的答案。

标签: java algorithm linked-list big-o binary-search


【解决方案1】:

while() 的第三行,

list.get( middle )

对于linkedList来说很昂贵,它是O(n / 2)平均情况== O(n)但对于arrayList它是O(1)所以即使算法缩小到O(log n)中的一个元素,访问数组每个循环中的元素都会导致 O(n) 到这给你 O(n log n)。

我猜如果你将 ArrayList 传递给函数,它会给你带来更好的性能。试一试。很好,你用List泛型接口实现了这个功能,你应该可以传递ArrayList。

并确保你研究了arraylist和linkedlist在访问/索引、读取、写入、搜索、克隆操作等方面的区别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 2010-10-25
    • 2012-09-04
    • 1970-01-01
    • 2017-09-28
    • 2013-02-04
    • 2012-06-05
    相关资源
    最近更新 更多