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' 算法实现起来比较复杂,容易出错且效果不显著,用来扯淡的成分比较大。