一個二分查找的小問題--由python四捨五入引發

在看算法圖解的過程瞭解到了不少算法的知識,但在中間也遇到了一個小問題。
下面咱們就看一下這個小問題時怎麼解決的。
下面是書中的源碼:python

def binary_search(list, item):
    low =  0
    high = len(list)
    while low <= high:
        mid = (low + high) / 2
        guess = list[mid]
        if guess == item:
            return mid
        if guess > item:
            high = mid - 1
        else:
            low = mid - 1
    return None

當咱們用下面的數據運行時:算法

list = [1, 2, 3, 4, 5]
item = 3
position = binary_search(list, item)
print(position)

會致使以下錯誤:測試

Traceback (most recent call last):
  File "binary_search.py", line 17, in <module>
    position = binary_search(list, item)
  File "binary_search.py", line 6, in binary_search
    guess = list[mid]
TypeError: list indices must be integers or slices, not float

上面信息的意思是索引類型錯誤,索引必須爲整型而不是float型。
這是由於python中除法即「/」會自動轉換類型。將沒法整除的數字轉換成浮點型。
下面是我一開始想到的解決辦法:code

def binary_search(list, item):
    low =  0
    high = len(list)
    while low <= high:
        mid = int((low + high) / 2)  # 將結果加一個類型轉換便可
        guess = list[mid]
        if guess == item:
            return mid
        if guess > item:
            high = mid - 1
        else:
            low = mid - 1
    return None

但當使用下面的數據進行測試時:索引

list = [1, 2, 3, 4, 5]
item = 5
position = binary_search(list, item)
print(position)

結果就是循環不會中止了。
爲了找到問題出在哪裏。咱們在循環體中加一個pirnt語句輸出一下mid源碼

def binary_search(list, item):
    low =  0
    high = len(list)
    while low <= high:
        mid = int((low + high) / 2)  # 將結果加一個類型轉換便可
        print(mid)
        guess = list[mid]
        if guess == item:
            return mid
        if guess > item:
            high = mid - 1
        else:
            low = mid - 1
    return None

仍是使用上面的數據運行一下。
能夠在終端中看到一直在循環輸出3。
出現這個問題緣由就處在int() 這個取整的操做他不是咱們理解的四捨五入,而是簡單的截取整數部分。
看下面的例子。it

a = 5.4
b = 5.5
c = 5.6
print(int(a))
print(int(b))
print(int(c))

運行後輸出爲:io

5
5
5

爲了解決這個問題咱們只須要給要取整的數加一個0.5便可。
上面的例子修改成:ast

a = 5.4
b = 5.5
c = 5.6
print(int(a + 0.5))
print(int(b + 0.5))
print(int(c + 0.5))

運行後輸出爲:module

5
6
6

因此上面的二分查找也就能夠修改爲:

def binary_search(list, item):
    low =  0
    high = len(list)
    while low <= high:
        mid = int((low + high) / 2 + 0.5)  # 爲了實現四捨五入加上一個0.5
        guess = list[mid]
        if guess == item:
            return mid
        if guess > item:
            high = mid - 1
        else:
            low = mid - 1
    return None

這樣解決了二分查找中的這個小問題。

相關文章
相關標籤/搜索