查詢演算法之二分查詢(折半查詢)Python

2021-10-24 04:06:42 字數 1963 閱讀 6681

對於順序表中已經排好序的表來說,除了上篇文章中的可以比較大小外,還可以有另外一種思路,就是二分查詢。因為已經排好序了,可以直接比較中間值(中位數),如果中位數比要查詢的數大,那麼要查詢的數可能在前半部分(至少不可能在後半部分),因為後半部分一定比中位數大,也一定比要查詢的數大。繼續,把前半部分當做乙個新的有序表,進一步比較中位數,直到找到要查詢的數或者不存在。

def binary_search(alist, item):

first = 0

last = len(alist) - 1

mid = 0

found = false

while first <= last and not found:

mid = (first + last) // 2

if alist[mid] == item:

found = true

elif alist[mid] < item: # 說明item一定在當前列表的後半部分,所以篩選範圍向後移動

first = mid + 1

else:

last = mid - 1 # 一定在前半部分

if found:

return mid

else:

return false

# 注意列表一定是有序的。

testlist = [0,1,2,8,13,17,19,32,42]

print(binary_search(testlist, 32))

print(binary_search(testlist, 17))

當然也可以用遞迴的形式做,在前面敘述中可以看出來,每次分割後,都把要比較的子列表當做乙個新的列表進一步比較,其實這就是遞迴的過程。因為遞迴每次的變數都會重複,這裡如果要輸出要查詢元素的下標,需要注意。

# 二分查詢的遞迴形式

def binary_search(alist, item):

first = 0

last = len(alist) - 1

if first <= last:

mid = (first + last) // 2

if alist[mid] == item:

# 注意返回的mid是此時的first和last的中間值

return mid

elif alist[mid] < item:

# 注意,因為本函式中每次都是初始化first和last

# 所以遞迴呼叫時,返回的miid是當前子列表的中間值

# 要想得到原始的中間值,需要起始位置

first = mid + 1

return first + binary_search(alist[first:], item)

else:

# 此時的開始的相對位置沒有改變,改變的只是結束位置

# 而結束位置並不影響子列表的中間值的相對原來的位置

# 所以此處不需要加上起始位置first。

last = mid - 1

return binary_search(alist[:last+1], item)

else:

return false

testlist = [0,1,2,8,13,17,19,32,42]

print(binary_search(testlist, 13))

print(binary_search(testlist, 8))

接下來再看一下時間複雜度。每一次比較,那麼剩下的還需要比較的就是n/2個元素(最壞的情況下),做第二次比較時,還剩下n/4個元素,也就是n/(2^i)

如果還剩乙個元素時,就只需要比較一次就知道結果了,所以n/(2^i)=1時就是最終結束時,可以看出來i=log(n),成對數形式的複雜度,比線性的複雜度要低一點,優化了一些。

PHP查詢演算法之二分查詢 折半查詢

折半查詢意為從把陣列從中間分成兩半,找到乙個中間值,然後進行判斷,首先這個陣列一定是從大到小或者從小到大排好序的。下面的 裡陣列是從小到大排序的。遞迴形式的 定義乙個從小到大排好序的陣列 arr 12 34 43 56 77 86 88 90 99 101 要查詢的數字 num 88 count c...

二分查詢 折半查詢 演算法

二分查詢也稱折半查詢 binary search 它是一種效率較高的查詢方法。但是,折半查詢要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列。首先,假設表中元素是按公升序排列,將表中間位置記錄的 關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功 否則利用中間位置 記錄將表分成前 後兩個子...

演算法 二分查詢(折半查詢)

二分查詢也稱折半查詢 binary search 它是一種效率較高的查詢方法。使用二分查詢的條件 1.必須採用順序儲存結構。2.必須按關鍵字大小有序排列。通俗一點的說 如果資料是乙個陣列,那麼這個陣列必須是有序的 時間複雜度 o log2n 如圖所示 下面我們來看c語言 include非遞迴實現 v...