溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python中搜索的示例分析

發(fā)布時間:2022-03-04 10:39:15 來源:億速云 閱讀:99 作者:小新 欄目:開發(fā)技術

這篇文章將為大家詳細講解有關python中搜索的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

    1. 普通搜索

    搜索是指從元素集合中找到某個特定元素的算法過程。搜索過程通常返回 True 或 False, 分別表示元素是否存在。
    python中提供了 in 方法可以判斷元素是否存在列表中:

    # python提供in函數(shù)進行搜索
    a=[3,4,5,8,'t']
    't' in a
    9 in a

    結果如下:

    python中搜索的示例分析

    2. 順序搜索

    順序搜索故名思義:從列表中的第一個元素開始,沿著默認的順序逐個查看, 直到找到目標元素或者查完列表。如果查完列表后仍沒有找到目標元素,則說明目標元素不在列表中。

    順序搜索過程:

    python中搜索的示例分析

    1.1 無序下的順序查找

    無序下的順序搜索很有特點,列表無序,只好一個一個去比較,尋找元素。

    #順序查找
    def sequentialsearch(testlist,item):
        pos=0
        found=False
        while pos<len(testlist) and not found:
            if testlist[pos]==item:
                found=True
            else:
                pos=pos+1
        return found

    結果如下:

    python中搜索的示例分析

    分析一下這種順序查找,這種查找方式,最好的方式就尋找一次就成功了,最壞的情況的需要查找n次,于是時間復雜度是O(n)

    1.2 有序下的順序查找

    有序下的順序查找就是所查找的列表是有序的,

    # 有序下的順序搜索
    def ordersearch(testlist,item):
        pos=0
        found=False
        stop=False
        while pos<len(testlist) and not found and not stop:
            if testlist[pos]==item:
                found=True
            else:
                if testlist[pos]>item:
                    stop=True
                else:
                    pos=pos+1
        return found

    結果如下:

    python中搜索的示例分析

    分析一下這種搜索方法,正常情況下來說,最好情況下,搜索1次就能成功,最差情況只需要n/2次即可搜索完成,但時間復雜度依舊是O(n),只有當列表中不存在目標元素時,有序排列的元素才會提高順序搜索的效率。

    2.二分查找

    二分查找:是利用列表有序的這個原理,從中間的元素著手。如果這個元素就是目標元素,那就立即停止搜索;如果不是,則可以利用列表有序的特性,排除一半的元素。如果目標元素比中間的元素大,就可以直接排除列表的左半部分和中間的元素。這是因為,如果列表包含目標元素,它必定位于右半部分。

    在有序整數(shù)列表中進行二分搜索:

    python中搜索的示例分析

    二分查找實現(xiàn)方式:

    def binarysearch(testlist,item):
        testlist.sort()#排序
        left=0#左指針
        right=len(testlist)-1#右指針
        found=False
        while left<=right and not found:
            mid=(left+right)//2#取中間值
            if testlist[mid]==item:
                found=True
            else:
                if testlist[mid]<item:
                    left=mid+1
                else:
                    right=mid-1
        return found

    看看效果:

    python中搜索的示例分析

    二分查找遞歸實現(xiàn):

    def binarysearch3(testlist,item):
         if len(testlist) == 0: 
            return False 
         else: 
            mid = len(testlist) // 2 
            if testlist[mid] == item: 
                return True 
            else: 
                if item < testlist[mid]: 
                    return binarysearch3(testlist[:mid], item) 
                else: 
                    return binarysearch3(testlist[mid+1:], item)

    看看效果:

    python中搜索的示例分析

    總結一下二分查找:在進行二分搜索時,每一次比較都將待考慮的元素減半,。那么,要檢查完整個列表,二分搜索算法最多要比較多少次呢?假設列表共有 n 個元素,第一次比較后剩下n 個元素,第 2 次比較2后剩下n /4個元素,接下來是n/8 ,然后是n/16 ,依此類推。列表能拆分多少次?

    二分搜索算法的表格分:

    python中搜索的示例分析

    拆分足夠多次后,會得到只含一個元素的列表。這個元素要么就是目標元素,要么不是。無論是哪種情況,計算工作都已完成。要走到這一步,需要比較 i 次,其中n 2 i {n}\over{2^i}
    2
    i
     
    n

     =1 。由此可得比較次數(shù)的最大值與列表的元素個數(shù)是對數(shù)關系。所以,二分搜索算法的時間復雜度是O ( l o g 2 n ) O(log_2 n)O(log
    2

     n)。

    3.散列查找

    散列查找:通過散列構建一個時間復雜度為 O(1)的數(shù)據(jù)結構。我們平常聽的最多哈希表就是散列的一種方式。
    散列表:散列表是元素集合,其中的元素以一種便于查找的方式存儲。散列表中的每個位置通常被稱 為槽,其中可以存儲一個元素。槽用一個從 0 開始的整數(shù)標記,例如 0 號槽、1 號槽、2 號槽, 等等。初始情形下,散列表中沒有元素,每個槽都是空的??梢杂昧斜韥韺崿F(xiàn)散列表,并將每個元素都初始化為 Python 中的特殊值 None。下圖展示了大小 m 為 11 的散列表。也就是說,表中有 m 個槽,編號從 0 到 10。

    有11 個槽的散列表:

    python中搜索的示例分析

    散列函數(shù):將散列表中的元素與其所屬位置對應起來。對散列表中的任一元素,散列函數(shù)返回 一個介于 0 和 m – 1 之間的整數(shù)。假設有一個由整數(shù)元素 54、26、93、17、77 和 31 構成的集 合。首先來看第一個散列函數(shù),它有時被稱作“取余函數(shù)”,即用一個元素除以表的大小,并將 得到的余數(shù)作為散列值(h(item) = item%11)。下圖給出了所有示例元素的散列值。取余函數(shù)是一個很常見的散列函數(shù),這是因為結果必須在槽編號范圍內(nèi)。

    使用余數(shù)作為散列值:

    python中搜索的示例分析

    計算出散列值后,就可以將每個元素插入到相應的位置,如圖 5-5 所示。注意,在 11 個槽 中,有 6 個被占用了。占用率被稱作載荷因子,記作λ \lambdaλ,定義如下:

    python中搜索的示例分析

    有 6 個元素的散列表:

    python中搜索的示例分析

    3.1 幾種散列函數(shù)

    給定一個元素集合,能將每個元素映射到不同的槽,這種散列函數(shù)稱作完美散列函數(shù)。如果元素已知,并且集合不變,那么構建完美散列函數(shù)是可能的。不幸的是,給定任意一個元素集合,沒有系統(tǒng)化方法來保證散列函數(shù)是完美的。所幸,不完美的散列函數(shù)也能有不錯的性能。

    • 折疊法:先將元素切成等長的部分(最后一部分的長度可能不同),然后將這些部分相加,得到散列值。假設元素是電話號碼 436-555-4601,以 2 位為一組進行切分,得到 43、65、55、46 和 01。將這些數(shù)字相加后,得到 210。

    • 平方取中法:先將元素取平方,然后提取中間幾位數(shù)。如果元素是 44,先計算 442=1936,然后提取中間兩位 93,繼續(xù)進行取余的步驟。

    • 字符編碼:采用python中的ord函數(shù)將單詞“cat”看作序數(shù)值序列,再將這些序數(shù)值相加,并采用取余法得到散列值。

    3.2 處理散列表沖突

    完美的散列表,一個元素只對應著一個卡槽,可是如果當2個元素被分配到一個卡槽時,必須通過一種系統(tǒng)化方法在散列表中安置第二個元素。這個過程被稱為處理沖突。

    開發(fā)定址法:在散列表中找到另一個空槽,用于放置引起沖突的元素。簡單的做法是從起初的散列值開始,順序遍歷散列表,直到找到一個空槽。注意,為了遍歷散列表,可能需要往回檢查第一個槽。(例如:將(54, 26, 93, 17, 77, 31, 44, 55, 20)放入卡槽中。)

    python中搜索的示例分析

    再散列:采用“加 3”探測策略處理沖突后的元素分布情況。發(fā)生沖突時,為了找到空槽,該策略每次跳兩個槽。

    python中搜索的示例分析

    平方探測:線性探測的一個變體,它不采用固定的跨步大小,而是通過再散列函數(shù)遞增散列 值。如果第一個散列值是 h,后續(xù)的散列值就是 h+1、h+4、h+9、h+16,等等。換句話說,平方探測的跨步大小是一系列完全平方。

    python中搜索的示例分析

    鏈接法:允許散列 表中的同一個位置上存在多個元素。發(fā)生沖突時,元素仍然被插入其散列值對應的槽中。不過, 隨著同一個位置上的元素越來越多,搜索變得越來越困難。

    python中搜索的示例分析

    3.3 散列表的實現(xiàn)(加1重復)

    哈希散列的實現(xiàn):

    #哈希表
    class HashTable:
        def __init__(self): 
            self.size = 11 
            self.slots = [None] * self.size 
            self.data = [None] * self.size
        def put(self, key, data): 
            hashvalue = self.hashfunction(key, len(self.slots)) 
            if self.slots[hashvalue] == None: 
                self.slots[hashvalue] = key
                self.data[hashvalue] = data 
            else: 
                if self.slots[hashvalue] == key: 
                    self.data[hashvalue] = data #替換 
                else: 
                    nextslot = self.rehash(hashvalue, len(self.slots)) 
                    while self.slots[nextslot] != None and self.slots[nextslot] != key: 
                        nextslot = self.rehash(nextslot, len(self.slots))
                    if self.slots[nextslot] == None: 
                        self.slots[nextslot] = key 
                        self.data[nextslot] = data
                    else: 
                        self.data[nextslot] = data #替換 
        def hashfunction(self, key, size): 
            return key%size 
        def rehash(self, oldhash, size): 
            return (oldhash + 1)%size
    
    #get函數(shù)
        def get(self, key): 
            startslot = self.hashfunction(key, len(self.slots)) 
            data = None 
            stop = False 
            found = False 
            position = startslot
            while self.slots[position] != None and not found and not stop: 
                if self.slots[position] == key: 
                    found = True 
                    data = self.data[position] 
                else:  
                    position=self.rehash(position, len(self.slots)) 
                    if position == startslot: 
                        stop = True 
                        return data 
        def __getitem__(self, key): 
            return self.get(key) 
        def __setitem__(self, key, data): 
            self.put(key, data)

    結果如下:

    python中搜索的示例分析

    我們分析一下散列查找:在最好情況下,散列搜索算法的時間復雜度是 O(1),即常數(shù)階。但可能發(fā)生沖突,所以比較次數(shù)通常不會這么簡單。

    關于“python中搜索的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

    AI