【问题标题】:recursive binary search of a sorted sublist排序子列表的递归二进制搜索
【发布时间】:2018-04-04 14:23:59
【问题描述】:

我正在尝试实现一个递归二进制搜索算法,它需要 4 个参数,一个列表,首先是排序子序列中第一项的整数索引,最后是排序子序列中最后一项的整数索引-sequence 和一个目标,它将与存储在列表中的值进行比较。

算法需要返回目标在已排序子序列中的位置(如果存在),如果不返回,则返回目标在已排序子序列中的位置。

这是我到目前为止所拥有的;

def binary_search(a_list, first, last, target):
    subMidpoint = (first + last) // 2
    if a_list[subMidpoint] == target:
        return subMidpoint
    else:
        if target < a_list[subMidpoint]:
            last = subMidpoint -1
            return binarySearch(a_list, first, last, target)
        else:
            first = subMidpoint +1
            return binarySearch(a_list, first, last, target)
    return first 

如果该项目不存在,我正在努力解决如何返回位置,任何帮助将不胜感激。但是,当前编译的代码返回“无”而不是索引位置。

非常感谢。

编辑;

感谢大家的帮助,我已经设法修改了最后一个子句,它已经通过了一些测试,但是当目标小于 first 中的最小值并且目标更大时,它会失败比 last 中的值。

这是修改后的最后一个子句。

    else:
    if target < a_list[subMidpoint]:
        last = subMidpoint -1
        return binary_search(a_list, first, last, target)
    else:
        first = subMidpoint +1
        return first

【问题讨论】:

  • 如果在过程中只剩下两个项目并且它们不是目标,那么目标的排序位置可能会在这些位置之间。
  • 注意这里的递归被破坏了。该函数被称为binary_search,但递归调用是对一个名为binarySearch 的函数。不幸的是,当你修复它时,当项目不在列表中时,你会得到一个最大递归错误,因为在这种情况下没有终端条件。如果您弄清楚终端条件,您也将回答您自己的问题。亲手完成几次这个过程总是一个好主意!
  • Python 的标准库中有一个bisect 模块。无需重新发明这个*。
  • 严格来说,二分查找只适用于 O(logn) 中的数组。如果你有一个(链接的)列表,那么扫描子列表 O(n) 是最好的解决方案。
  • @maraca 严格来说,这在这里无关紧要,因为 Python 中的 list 没有实现为链表。 :-)

标签: python algorithm recursion binary-search


【解决方案1】:

您的描述中几乎有您的答案:如果您找到相邻的项目,比如位置 5 和 6,但您还没有找到该项目,那么它将被插入这两个项目之间。由于列表索引增长到上限,因此您将返回两者中的较高者——在本例中为 6

因此,您的逻辑将在您的最后一个子句中

else:
    if subMidpoint == first:
        return last
    else:
        first = subMidpoint +1
        return binarySearch(a_list, first, last, target)
  • return first放到底部;你应该能够达到那个声明。
  • 学习elif关键字;您的程序将更具可读性。

【讨论】:

    【解决方案2】:

    已解决,谢谢大家。不是最干净的解决方案,但它有效。

    def binary_search(a_list, first, last, target):
    subMidpoint = (first + last) // 2
    if target < a_list[first]:
        return first
    elif target > a_list[last]:
        return last +1
    elif a_list[subMidpoint] == target:
        return subMidpoint
    elif target < a_list[subMidpoint]:
        last = subMidpoint -1
        return binary_search(a_list, first, last, target)
    else:
        first = subMidpoint +1
        return first
    

    【讨论】:

      最近更新 更多