1. 程式人生 > >python資料結構與演算法27 排序與查詢 順序查詢

python資料結構與演算法27 排序與查詢 順序查詢

現在我們轉向排序與查詢的內容,這一節研究查詢,後半章研究排序。查詢是在一個數據集裡找到某個特定元素的演算法過程。查詢的結果可能是找到或沒找到,所以返回值是TrueFalse。這裡為簡單起見,我們只涉及與列表成員相關的問題。

python裡,有一個非常簡單的方法查詢某資料是否在列表裡,使用in操作符:

>>> 15in [3,5,2,4,1]

False

>>> 3in [3,5,2,4,1]

True

>>> 

雖然這樣寫很簡單,不過這個演算法後面的處理過程我們還是要學習,查詢有很多種方法,我們感興趣的是演算法以及演算法之間的比較。

順序查詢

資料儲存在資料集,象list一類的集合,我們說他們是線性的或者是順序的。每個資料項都儲存有相對的位置。在python的列表裡,每個項的相對位置用index值表示。Index是有序的,這樣就產生了第一種查詢演算法:順序查詢

如圖1所示,從列表的第一個元素開始,一個接一個檢查,直到找到或全部找完,如果找完全部項,可以判斷這個項在列表中不存在。


以下是這種演算法的實現。這個函式的引數有:列表,待查項,返回值是布林值。布林變數found初始值為False,如果找到就被賦值True.

1

def sequentialSearch(alist, item):

2

    pos = 0

3

    found = False

4

5

    while pos < len(alist) and not found:

6

        if alist[pos] == item:

7

            found = True

8

        else:

9

            pos = pos+1

10

11

    return found

12

13

testlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]

14

print(sequentialSearch(testlist, 3))

15

print(sequentialSearch(testlist, 13))


順序查詢的效能分析

要分析查詢演算法,先要決定一個基本計算單位。記得一般是解決問題的每一次重複算做一步。對查詢來說,應該就是比較是與不是的次數。另外的一個假設就是列表是無序的,資料項在列表裡隨機安放,換句話說,資料項可能在列表的任何一個位置。

如果資料項不在列表裡,唯一的判定辦法就是把全部項逐個比較一番。如果表中有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後立即終止查詢。