Если добавить в функцию оператор print()
и использовать меньший пример, вы увидите проблему:
def bi_search(nums, find):
print((nums, find))
...
print(bi_search(list(range(10)), 7))
Вывод:
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 7) # Looks good.
([5, 6, 7, 8, 9], 7) # Also good.
2 # Doh!
Проблема в том, чтоВы возвращаете индекс в последний проверенный список , а не индекс начальный список .Чтобы ваш подход работал, вам нужно передавать больше информации через рекурсивные вызовы - и это становится сложнее.
Другой подход состоит в том, чтобы передавать полный список для каждого вызова и вместо этого корректировать нижнюю / верхнюю границыдля поиска, как вы идете.Это также позволяет избежать создания новых списков при каждом вызове.Например:
def bi_search(nums, find, i = None, j = None):
# Setup.
N = len(nums)
if i is None:
i = 0
j = N - 1
# Base case for failure.
if j < i:
return None
# Success or recurse.
mid = (i + j) // 2
if find == nums[mid]:
return mid
elif find < nums[mid]:
return bi_search(nums, find, i, mid - 1)
else:
return bi_search(nums, find, mid + 1, j)