递归二进制搜索不能系统地工作

时间:2019-01-05 13:01:37

标签: python algorithm recursion search

我正在用迭代递归方法实现二进制搜索算法。

输入的第一行包含一个整数n和一个n对成对的不同正整数序列(按升序排列)。 下一行包含一个整数kk个正整数。

对于从0到i的所有k - 1,输出一个索引0 <= j <= n-1,使a_j = b_i-1(如果没有这样的索引)。 (针对每种算法实现)

a和b分别是每个序列的元素。

输入:

5 1 5 8 12 13
5 8 1 23 1 11

输出:

2 0 -1 0 -1
2 0 -1 0 -1
2 0 -1 0 -1

我设法实现了迭代,递归版本和线性搜索版本。

import sys

def binary_search_it(a, x):
    left, right = 0, len(a) - 1
    while left <= right:
        mid = left + (right - left) // 2
        if x == a[mid]:
            return mid
        # left--mid--x--right
        if a[mid] < x:
            left = mid + 1
        # left--x--mid--right
        elif x < a[mid]:
            right = mid - 1
    return - 1

def binary_search_rec(a, x):
    left, right = 0, len(a) - 1
    if right < left:
        return left - 1
    mid = left + (right - left) // 2
    if x == a[mid]:
        return mid
    if x < a[mid]:
        return binary_search_rec(a[: mid - 1], x)
    else:
        return binary_search_rec(a[mid + 1:],x)


def linear_search(a, x):
    for i in range(len(a)):
        if a[i] == x:
            return i
    return -1

if __name__ == '__main__':
    input = sys.stdin.read()
    data = list(map(int, input.split()))
    n = data[0]
    m = data[n + 1]
    a = data[1 : n + 1]
    for x in data[n + 2:]:
        # replace with the call to binary_search when implemented
        print(binary_search_it(a, x), end=' ')
    print('\n')
    for x in data[n + 2:]:
        print(linear_search(a, x), end=' ')
    print('\n')
    for x in data[n + 2:]:
        print(binary_search_rec(a, x), end = ' ')

到目前为止,一切都很好,对于上面的代码示例,这三种实现都返回相同的输出。

如果我尝试使用其他示例数据集,那么我的递归方法就会遇到问题

输入:

5 1 2 3 4 5
5 1 2 3 4 5

输出(预期):

0 1 2 3 4
0 1 2 3 4
0 -1 2 0 0

有人可以向我解释我的代码流程以及如何识别问题吗?

2 个答案:

答案 0 :(得分:2)

此实现存在多个问题:

  • 使用切片非常昂贵,并使该算法成为 O(n)

  • 递归算法永远不会返回-1来指示未找到该项目。

二进制搜索的递归实现仍需要跟踪leftright O(log n)

def binary_search_rec(a, x):
    return _binary_search(a, x, 0, len(a) - 1)

def _binary_search(a, x, left, right):
    if right < left:
        return -1

    mid = (right + left) // 2
    if x == a[mid]:
        return mid
    if x < a[mid]:
        return _binary_search(a, x, left, right - 1)
    else:
        return _binary_search(a, x, left + 1, right)

答案 1 :(得分:1)

问题是这一行:

...
if x < a[mid]:
    return binary_search_rec(a[: mid - 1], x)  <---
...

切片的上限是专有的。请参阅,例如this question了解更多详情。

如何查找此类问题?通过充分了解算法和语言以通过读取代码或通过调试器来识别代码中的错误。每个适用于python或独立的IDE都应带有调试器。学会使用一个应该是任何入门程序员的头等大事。