如何使用二进制搜索来搜索大量名称

时间:2018-07-05 10:36:56

标签: python algorithm sorting binary-search

我是python的新手,我在一个大的值数组上实现二进制搜索,其中Array的长度为258000,我在线性搜索上测试了我的代码,当它超过最大递归深度时,它也崩溃了,这就是为什么我使用二进制但是二进制文件也不能在那个大数组上工作,当我在小数组上测试我的代码时,它可以正常工作,这是一个代码:

A = ['John', 'William', 'James', 'Charles', 'George', 'Frank']
names = sorted(A)
print(names)
n = len(names) - 1

low = 0
high = n
key = "James"

def binarysearch(a, l, h, k):

    if h < l:
        return l - 1
    mid = l + (h - l // 2)
    if k == names[mid]:
        return mid
    elif key < names[mid]:
        return binarysearch(a, l, mid-1, k)
    else:
        return binarysearch(a, mid+1, h, k)

index = binarysearch(names, low, high, key)

print("The given Name ", key, "is a Place ", index)

我知道如何增加我尝试过的sys.setrecursionlimit(),但是由于它超出了RAM限制I have use bisect code of python and it works fine,它仍然可以杀死,但是由于我是python的新手,所以我想吸收更深入的概念算法,而不是内置函数,如果有人可以帮助我更正此代码,我将不胜感激,谢谢

3 个答案:

答案 0 :(得分:3)

您根本不需要递归。您可以迭代方式进行二进制搜索。但是,即使使用递归,也不应使用此类数组达到最大递归深度。遇到此问题的原因是您没有正确执行二进制搜索。

mid = l + (h - l // 2)

这显然是错误的,因为l // 2将首先被评估。您想要的是:

mid = l + (h - l) // 2

此外,当l - 1返回h < l时,我没有合理的理由。通常,您应该返回-1表示未找到密钥。 l - 1在某个递归步骤可能会为初始调用提供有效的索引。

最后,如果未对列表进行排序,则没有必要先对其进行排序,然后再进行二进制搜索,除非您在同一数组上进行了大量搜索,因为排序要比简单的线性搜索花费更多的时间。 / p>

答案 1 :(得分:1)

如果字符串数组不会长时间更改或不会非常频繁地更改并且搜索将非常频繁地使用,则可以使用Trie数据结构,这将增强您的字符串时间的复杂度以空间的复杂度为代价。 最糟糕的时间复杂度是O(length of the longest string in that array)

答案 2 :(得分:0)

这不是一个巨大的列表,只需使用list.index

x = [random.random() for _ in range(258000)] + [0.99]
%timeit x.index(0.99)
# 7.97 ms ± 703 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

示例

a = ['John', 'William', 'James', 'Charles', 'George', 'Frank']
a.index('James')  # --> 2