TAoCP 6.1 Sequential Searching 順序查找算法的實現

p.396 算法 S

 

人類史上最簡單最直觀也是效率最低的查找算法。

 

# coding: utf-8

"""
算法 S

遍歷 lst 逐個查找 key 。
"""
def sequential_search(key, lst):
    n = len(lst)

    i = 0 
    while (i < n): 
        if lst[i] == key:
            return i
        else:
            i += 1

    return None

if __name__ == "__name__":
    l = [5,2,1,3,6,9]

    assert sequential_search(3, l) == 3
    assert sequential_search(7, l) is None

 

 

p.396 算法 Q

 

Q 算法將 key 追加到列表的末尾,然後通過對比 i 來判斷查找是否成功,它比起 S 算法減少了內循環判斷的次數。

 

# coding: utf-8

"""
算法 Q

將 key 追加到 lst 的末尾,通過 i 來判斷查找是否成功。
"""
def quick_sequential_search(key, lst):
    n = len(lst)

    lst.append(key)
    new_n = len(lst)

    i = 0 
    while (i < new_n):
        if lst[i] != key:
            i += 1
        else:   
            break

    if i < n:
        return i
    else:
        return None

if __name__ == "__main__":
    l = [5,2,1,3,6,9]

    assert quick_sequential_search(3, l) == 3
    assert quick_sequential_search(7, l) is None

 

 

p.398 算法 Q'

 

Q' 算法改進自 Q 算法,主要改進是以 2 爲步進增長 i ,每次將 key 和 lst[i] 、 lst[i+1] 兩個元素進行對比,節省了一半 i += 1 的執行時間。

當然,因爲列表的長度可能是偶數(% 2 == 0),也可能是奇數(% 2 != 0),因此要小心處理長度爲奇數的情況。

 

# coding: utf-8

"""
算法 Q'

以 2 爲步進遞增 i ,每次將 key 和 lst[i] 、 lst[i+1] 比對。
如果 len(lst) 不能被 2 整除,那麼先單獨處理 lst[0] 。
"""
def quicker_sequential_search(key, lst):
    n = len(lst)
    i = 0 

    if n % 2 != 0:
        if lst[0] == key:
            return 0
        else:
            i += 1
    
    lst.append(key)
    while i < n:    
        if lst[i] == key:
            return i
        elif lst[i+1] == key:
            return i+1 if i+1 < n else None
        else:
            i +=2 

if __name__ == "__main__":
    # len(l) % 2 != 0
    l = [5,2,6,3,1]
    assert quicker_sequential_search(6, l) == 2
    assert quicker_sequential_search(7, l) is None

    # len(another) % 2 == 0
    another = [5,2,6,3,1,0]
    assert quicker_sequential_search(6, another) == 2
    assert quicker_sequential_search(7, another) is None

 

 

p.398 算法 T

 

算法 T 是最簡單(也是最低效)的已排序列表的查找算法。

 

# coding: utf-8

"""
算法 T

最簡單(也是效率最低的)對已排序列表進行查找的算法。
"""
def sequential_search_in_ordered_table(key, lst):
    assert sorted(lst) == lst 

    n = len(lst)
    i = 0 
    while i < n:
        if key <= lst[i]:
            return i if key == lst[i] else None
        else:
            i += 1

if __name__ == "__main__":
    l = [1, 2, 3, 5, 6]

    assert sequential_search_in_ordered_table(3, l) == 2
    assert sequential_search_in_ordered_table(4, l) is None
    assert sequential_search_in_ordered_table(10, l) is None

 

現在看來,也只有 S 算法在比較簡單的場合在使用,一般情況下,對比較大的列表先進行排序然後再進行查找,或者使用其他數據結構來處理(比如樹和哈希表)也可以得到更好的效率。

 

而 Q 和 Q' 算法實現起來比較複雜,容易出錯且效果不顯著,用來扯淡的成分比較大。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章