1. 程式人生 > 實用技巧 >資料結構與演算法——搜尋(二分法)

資料結構與演算法——搜尋(二分法)

搜尋

搜尋是在一個專案集合中找到一個特定專案的演算法過程。搜尋通常的答案是真的或假的,因為該專案是否存在。 搜尋的幾種常見方法:順序查詢、二分法查詢、二叉樹查詢、雜湊查詢

二分法查詢

二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。首先,假設表中元素是按升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。

二分法程式碼實現

(1)非遞迴方法

# import pdb
# pdb.set_trace()
def binary_search(alist, item):
    first = 0            # 子序列的頭下標
    last = len(alist)-1  # 子序列的尾下標
    while first <=last :
        mid = (first+last)//2  # 子序列下標的中間數
        if alist[mid] == item:
            return True
        elif alist[mid] >item :
            last = mid -1     # mid 已經判過了所以尾部-1
        else:
            first = mid + 1   # mid 已經判過了所以頭部+1
    return False

testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,45]
print(binary_search(testlist, 3))
print(binary_search(testlist, 45))
False
True

(2)遞迴方法

def binary_search(alist, item):
    if len(alist) == 0:
        return False
    else:
        mid = (len(alist)-1)//2    # 取子序列下標的中間數
        if alist[mid] == item:
            return True
        elif alist[mid] < item:
            return binary_search(alist[mid+1:], item)
        else:
            return binary_search(alist[:mid], item)     # 切片右邊為開區間,相當於取mid-1
testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,45]
print(binary_search(testlist, 3))
print(binary_search(testlist, 42))
False
True

時間複雜度

  • 最優時間複雜度:O(1)
  • 最壞時間複雜度:O(logn)