1. 程式人生 > >演算法之二分查詢PK線性查詢

演算法之二分查詢PK線性查詢

列表查詢(線性查詢)

本質就是列表的index()
順序查詢 也叫線性查詢,從列表第一個元素開始,順序進行搜尋,知道找到元素或搜尋到列表最後一個元素為止。

以下是示例程式碼:


def line_search(li, val):
    for key, value in enumerate(li):
        if value == val:
            return key
    else:
        return None

二分法查詢(前提必須是一個有序的列表)

通過取中間值,選擇候選區,如果中間值大於要查詢的值,則證明候選區在左邊,更改右邊的最大值為中間值的上一位,反之如果中間值小於要查詢的值, 證明候選區在右邊,則改變左邊最小的值為中間值的下一位。如果右邊的最大值跑到了左邊最小值的左邊,則說明候選區沒有要找的值,程式結束。

def binary_search(li, val):
    left = 0 # 最小值的下標
    right = len(li)-1 # z最大值的下標
    while left <= right:  # 候選區有值
        # mid是中間值的下標
        mid = (left+right) // 2
        if li[mid] == val:  # 找到了就返回索引
            return mid
        elif li[mid] < val:  # 如果中間值小於找的值,說明要找的值在右邊候選區
            left = mid + 1
        else:
            right = mid - 1
    else:
        return None

二分法和線性查詢的比較


import time

def cal_time(func):
    def inner(*args):
        start = time.time()
        func(*args)
        end = time.time()
        print('run coding time %s' % (end-start))
    return inner
from cal_time import cal_time



@cal_time
def binary_search(li, val):
    left = 0
    right = len(li)-1
    while left <= right:  # 候選區有值
        # mid是中間值的下標
        mid = (left+right) // 2
        if li[mid] == val:  # 找到了就返回索引
            return mid
        elif li[mid] < val:  # 如果中間值小於找的值,說明要找的值在右邊候選區
            left = mid + 1
        else:
            right = mid - 1
    else:
        return None
li = list(range(10000000))
binary_search(li, 6678)

@cal_time
def line_search(li, val):
    for key, value in enumerate(li):
        if value == val:
            return value
    else:
        return None


line_search(li, 56567856)

gao

可以看出線性查詢的速度已經0.6秒了,而二分查詢依然瞬間出來,固然二分查詢的效率是很高的,但是他有一個最大的前提條件就是必須是在已經排好序的列表中,也就是說如果你的需求是在大量資料中查詢一次,沒必要費勁的做二分查詢,因為本身的資料排序所需要的時間是遠遠要超過列表的線性查詢的。