【问题标题】:Recursive binary search not working systematically递归二进制搜索无法系统地工作
【发布时间】:2019-05-31 19:28:49
【问题描述】:

我正在使用 iterativerecursive 方法实现二分搜索算法。

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

对于从 0 到 k - 1 的所有 i,输出一个索引 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

有人可以解释一下我的代码中的流程以及您是如何识别问题的吗?

【问题讨论】:

    标签: python algorithm recursion search


    【解决方案1】:

    这个实现存在多个问题:

    • 使用切片代价高昂,使得该算法O(n)

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

    二分查找的递归实现仍需要跟踪leftrightO(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)
    

    【讨论】:

      【解决方案2】:

      问题出在这一行:

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

      切片的上限是独占。参见例如this question 了解更多详情。

      如何发现此类问题?通过对算法和语言的了解足以通过阅读代码来识别代码中的错误,或者通过调试器。每个可用于 python 或独立的 IDE 都应该附带一个调试器。学习使用一个应该是任何初学者的首要任务之一。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-30
        • 2021-04-28
        • 2020-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多