python資料結構與演算法27 排序與查詢 順序查詢
現在我們轉向排序與查詢的內容,這一節研究查詢,後半章研究排序。查詢是在一個數據集裡找到某個特定元素的演算法過程。查詢的結果可能是找到或沒找到,所以返回值是True或False。這裡為簡單起見,我們只涉及與列表成員相關的問題。
在python裡,有一個非常簡單的方法查詢某資料是否在列表裡,使用in操作符:
>>> 15in [3,5,2,4,1]
False
>>> 3in [3,5,2,4,1]
True
>>>
雖然這樣寫很簡單,不過這個演算法後面的處理過程我們還是要學習,查詢有很多種方法,我們感興趣的是演算法以及演算法之間的比較。
順序查詢
資料儲存在資料集,象list一類的集合,我們說他們是線性的或者是順序的。每個資料項都儲存有相對的位置。在python的列表裡,每個項的相對位置用index值表示。Index是有序的,這樣就產生了第一種查詢演算法:順序查詢
如圖1所示,從列表的第一個元素開始,一個接一個檢查,直到找到或全部找完,如果找完全部項,可以判斷這個項在列表中不存在。
以下是這種演算法的實現。這個函式的引數有:列表,待查項,返回值是布林值。布林變數found初始值為False,如果找到就被賦值True.
|
順序查詢的效能分析
要分析查詢演算法,先要決定一個基本計算單位。記得一般是解決問題的每一次重複算做一步。對查詢來說,應該就是比較是與不是的次數。另外的一個假設就是列表是無序的,資料項在列表裡隨機安放,換句話說,資料項可能在列表的任何一個位置。
如果資料項不在列表裡,唯一的判定辦法就是把全部項逐個比較一番。如果表中有n個數據,順序查詢就需要n次比較。但是分析沒有這麼簡單,有三種情形可能發生,最好的情況下,第一個項就是我們要找的,只有1次比較。最差的情況下,需要n次比較,全部比較過之後才知道找不到。
平均情況如何呢?在平均情況下,我們會發現是列表的一半,即平均要比較n/2次。回想一下,不論係數多大,在我們這裡無關緊要,也就是說順序查詢的效能是O(n)。表1是各種結構的彙總。
Table 1: Comparisons Used in a Sequential Search of an Unordered List |
|||
Case |
Best Case |
Worst Case |
Average Case |
item is present |
1 |
n |
n/2 |
item is not present |
n |
n |
n |
前面我們有一個假設,就是資料項在列表裡面位置是隨機的,所以之間沒有相對順序。但是假如表中資料項以某種方式排序了,怎樣來查詢呢?又怎樣利用這個特性來獲得更好的效率呢?
假如列表元素是升序排列的,即從低到高。如果資料項在列表中仍然是隨機的,我們將仍然比較相同的次數來找到它。然而,如果元素不在列表裡,在效能上會稍有提高。如圖2所示的查詢50的過程。注意資料項與列表元素逐個比較直到54,這裡我們遇到個特殊情況,不但54不是我們要找的,而且54後面的元素也不是我們要找的,因為元素是有序的!這時演算法就不必繼續遍歷所有元素後才報告找不到,它可以在找到54後立即終止查詢。