二分搜索与线性搜索奇怪的时间

Posted

技术标签:

【中文标题】二分搜索与线性搜索奇怪的时间【英文标题】:Binary Search vs. Linear Search Strange Times 【发布时间】:2021-07-25 18:41:14 【问题描述】:

我有一个大约 10 万个整数的列表,我正在测试线性搜索与二进制搜索的概念。看起来我的线性搜索实际上比我的二进制搜索快。我不确定我明白为什么会这样。有什么见解吗?

看起来我的 cpu 在线性搜索中也受到了很大的打击。


def linear_search(big_list, element):
    """
    Iterate over an array and return the index of the first occurance of the item.

    Use to determine the time it take a standard seach to complate.
    Compare to binary search to see the difference in speed.

    % time ./searchalgo.py
    Results: time ./main.py  0.35s user 0.09s system 31% cpu 1.395 total

    """
    for i in range(len(big_list)):
        if big_list[i] == element:
            # Returning the element in the list.
            return i
    return -1

print(linear_search(big_list, 999990))

def linear_binary_search(big_list, value):
    """
    Divide and concuer approach
     - Sort the array.
     - Is the value I am searching for equal to the middle element of the array.
     - Compare is the middle element smaller orlarger than the element you are looking for?
        - If smaller then perform linear search to the right.
        - If larger then perform linear seach to the left.

    % time ./searchalgo.py
    Results:  0.57s user 0.18s system 32% cpu 2.344 total
    """
    big_list = sorted(big_list)
    left, right = 0, len(big_list) - 1
    index = (left + right) // 2
    while big_list[index] != value:
        if big_list[index] == value:
            return index
        if big_list[index] < value:
            index = index + 1
        elif big_list[index] > value:
            index = index - 1
        print(big_list[index])
# linear_binary_search(big_list, 999990)
Output of the linear search time:
./main.py  0.26s user 0.08s system 94% cpu 0.355 total


Output of the binary search time:
./main.py  0.39s user 0.11s system 45% cpu 1.103 total

【问题讨论】:

block cmets中的结果是我收到的初始结果。我更新了每个以尝试提高效率。底部结果是我算法的最终结果。 您的第二种算法实际上并不是二分搜索。您在第一次迭代的中间开始索引,但从那时起,您修改index 的唯一时间是在其中添加或减去 1。对于每次迭代,您需要将索引移动到当前块的中间进行检查。 您也不应该在“二进制”搜索例程中对输入数组进行排序。它应该已经预先排序。截至目前,这些时间安排并不公平 如果你使用 bisect_left,python 实际上有一个内置的二进制搜索,那么你不必担心实际实现它是否正确...... @PaulM。感谢那。是的,我明白你现在在说什么。我实现了这个,现在得到“./main.py 0.27s user 0.08s system 82% cpu 0.421 total”,这是时间上的改进,但我的 CPU 越来越多。 【参考方案1】:

由于单次遍历,您的第一个算法时间复杂度为 O(n)。但是在你第二次遍历的情况下,首先你对需要 O(nlogn) 时间的元素进行排序,然后搜索它需要 O(logn)。所以你的第二个算法的时间复杂度将是 O(nlogn) + O(logn) 这比你的第一个算法的时间复杂度要大。

【讨论】:

【参考方案2】:
def binary_search(sorted_list,target):
    if not sorted_list:
       return None
    mid = len(sorted_list)//2
    if sorted_list[mid] == target:
       return target
    if sorted_list[mid] < target:
       return binary_search(sorted_list[mid+1:],target)
    return binary_search(sorted_list[:mid],target)

我很确定实际上会以递归方式正确实现二进制搜索(这对我的大脑来说更容易处理)......还有内置的 bisect 库,它基本上为你实现了 binary_search

【讨论】:

以上是关于二分搜索与线性搜索奇怪的时间的主要内容,如果未能解决你的问题,请参考以下文章

如何使用伪代码开发线性搜索和二分搜索算法。?

为啥我们不能在跳转搜索中使用二分搜索而不是线性搜索?

为啥我的线性搜索比我在 Python3 中的二分搜索运行得更快?

什么时候顺序搜索比二分搜索好?

Python算法-冒泡排序、线性和二分搜索

线性和二进制搜索