二进制搜索算法测试重复值

时间:2019-03-05 15:53:07

标签: python algorithm

以下python代码似乎正常工作。如果我根据注释更改代码,它似乎仍然有效。如果我使用high = middle而不是high = middle - 1而不是low = middle而不是low = middle + 1时,算法是否会失败?

haystack = [3,5,7,8,9,23,65,89,100]
needle = 89
low = 0
high = len(haystack)

while (low < high):
  middle = (high + low)//2
  if (needle < haystack[middle] ):
     high = middle - 1 # what about just high = middle?
  elif (needle > haystack[middle]):
    low = middle + 1 # what about just low = middle?
  elif (needle == haystack[middle]):
    print ("The needle was found at index " + str (middle))
    break

3 个答案:

答案 0 :(得分:2)

那是因为您仅考虑值在列表中的情况(也许在某些情况下列表包含元素并且需要这些行,但我想不到其中之一) 考虑以下简单情况:

haystack = [1,2]
needle = 3
the rest of the code...

如果没有当前版本的代码,您将陷入无限循环。

注意:如@ vivek_23所述,您已经在检查中间位置,因此不需要进行额外的迭代。

答案 1 :(得分:0)

为使循环完成,每次迭代必须将范围至少减小1。如果没有,则将得到无限循环。

如果您到达low是偶数且high = low+1的地步,则middle的计算将始终返回low。您将不断测试相同的位置。

答案 2 :(得分:0)

关于为什么要进入无限循环的解释与您的条件有关:

while (low < high):

不更新条件(低或高)将意味着您的循环条件不会改变,low(如果开始低于高)将永远小于high

另一个注意事项是,它将有助于(您)将代码分解为功能。将来,它将使您的调试过程更加轻松。这是一个不太Python的实现:

def binary_search(sorted_list, target_value, low, high):
    if (low > high):
        return False
    mid = (low + high) // 2

    if (mid == 0 and sorted_list[mid] != target_value):
        return False
    if sorted_list[mid] == target_value:
        return True
    elif sorted_list[mid] < target_value:
        return binary_search(sorted_list, target_value, mid + 1, high)
    else:
        return binary_search(sorted_list, target_value, low, mid)

如果要确保可以访问列表中的每个项目,请尝试测试算法是否找到列表中的所有内容:

sorted_list = [1, 2, 3, 4, 5, 6, 7, 8, 8, 9]
not_in_list = 42


def test_binary_search(sorted_list):
    for each_item in sorted_list:
        found = binary_search(sorted_list, each_item, 0, len(sorted_list) - 1)
        if not found:
            print("{} not found by binary_search".format(each_item))
        else:
            print("found {} ".format(each_item))


test_binary_search(sorted_list)

类似地,当给定不在列表中的项目时,您希望算法能够正确运行。

def test_item_not_found(sorted_list, item):
    expected = False
    actual = binary_search(sorted_list, item, 0, len(sorted_list) - 1)
    status = "Passed" if actual == expected else "Failed"
    print("status {} expected: {}, actual: {}".format(status, expected, actual))


test_item_not_found(sorted_list, not_in_list)