python實現各種常用演算法之搜尋演算法(12)

2021-10-01 23:47:51 字數 3908 閱讀 8344

順序搜尋也稱為線性搜尋,屬於無序查詢演算法。

演算法原理

思路:

從資料結構線性表的一端開始,順序掃瞄,依次將掃瞄到的結點關鍵字與給定值 k 相比較,

若相等則表示查詢成功;

若掃瞄結束仍沒有找到關鍵字等於 k 的結點,表示查詢失敗。

複雜度分析

演算法實現

"""

思路:從順序表的頭部依次遍歷元素,判斷是否匹配,

若匹配則查詢成功,若不匹配則遍歷下乙個元素。

"""def

sequence_search

(sequence,target)

:for i in

range

(len

(sequence)):

if target==sequence[i]

:return i

return

none

if __name__ ==

'__main__'

: sequence=[99

,12,33

,74,521,13

,14] target=

521print

(sequence_search(sequence,target)

)

二分搜尋也稱折半搜尋(binary search),它是一種效率較高的搜尋方法。但是,二分搜尋要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列。

基本思想:

複雜度分析

總共有 n 個元素。

第 1 次折半:還剩 n/2 個元素

第 2 次折半:還剩 n/4 個元素

第 3 次折半:還剩 n/8 個元素

第 k 次折半:還剩 n/2^k 個元素

最壞的情況下,最後還剩 1 個元素,令 n/2^k = 1,得 k=logn,時間複雜度 o(logn)。

演算法實現

def

binary_search

(sorted_sequence,target)

: left=

0 right=

len(sorted_sequence)-1

""" 思路:每次查詢查詢範圍內的"中間位置"的結點,

若該節點不是所需,則縮小查詢範圍為前半部分或後半部分。

"""while

(left<=right)

: midpoint=

(left+right)//2

current_item=sorted_sequence[midpoint]

if current_item==target:

return midpoint

elif targetright=midpoint-

1else

: left=midpoint+

1return

none

if __name__ ==

'__main__'

: sorted_sequence =

[i for i in

range(1

,999,2

)]print

(binary_search(sorted_sequence, target=

521)

)

拓展

三分搜尋:就是在二分搜尋的基礎上,將區間分為三個區間做判斷,因此存在 5 個條件判斷。

def

ternary_search

(sorted_sequence, target)

: left =

0 right =

len(sorted_sequence)-1

while

(left <= right)

: third1 =

(right-left)//3

+left

third2 =2*

(right-left)//3

+left

if(sorted_sequence[third1]

== target)

:return third1

elif

(sorted_sequence[third2]

== target)

:return third2

elif

(target < sorted_sequence[third1]):

right = third1-

1elif

(target > sorted_sequence[third2]):

left = third2+

1else

: left = third1+

1 right = third2-

1return

none

鍥子

通過模擬,我們可以將查詢的點改進為如下: mid=left+(key-a[left])/(a[right]-a[left])*(right-left),也就是將上述的比例引數 1/2 改進為自適應的,根據關鍵字在整個有序表中所處的位置,讓 mid 值的變化更靠近關鍵字 key,這樣也就間接地減少了比較次數。

演算法原理

適用性: 對於表長較大,而關鍵字分布又比較均勻的查詢表來說,插值搜尋演算法的平均效能比折半搜尋要好的多。反之,陣列中如果分布非常不均勻,那麼插值搜尋未必是很合適的選擇。

基本思想:基於二分搜尋演算法只是在取"中點"的時候把比例引數 1/2 修改為自適應引數,可以提高搜尋效率。當然,差值搜尋也屬於有序搜尋。

複雜度分析

演算法實現

def

insert_search

(sorted_sequence, target)

: left =

0#右側取序列最大值-1

right =

len(sorted_sequence)-1

while

(left <= right)

:#自適應中點值=左+((目標值-最小值)*陣列長度)//(最大值-最小值)

midpoint = left +

((target-sorted_sequence[left])*

(right-left))//

( sorted_sequence[right]

-sorted_sequence[left]

)# 比例引數修改

#中點值小於0或者大於等於最大長度界限,不存在,返回空

if midpoint <

0or midpoint >=

len(sorted_sequence)

:return

none

current_item = sorted_sequence[midpoint]

#當前值等於目標值,返回中點值

if current_item == target:

return midpoint

#目標值小於當前值,中點值-1為新的右邊界

elif target < current_item:

right = midpoint-

1else

:#否則大於當前值,左側+1為新的左邊界

left = midpoint+

1return

none

python實現各種常用演算法之資料結構(1)

棧 stack 又名堆疊,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。棧允許進行插入和刪除操作的一端稱為棧頂 top 另一端為棧底 bottom 棧底固定,而棧頂浮動 棧中元素個數為零時稱為空棧。插入一般稱為進棧 push 刪除則稱為退棧 pop 由於堆疊資料結構只允許在一...

python實現各種常用演算法之資料結構(7)

並查集的介紹 建立乙個 union find 的類,並初始化。初始化兩個字典,乙個儲存節點的父節點,另外乙個儲存父節點的大小。初始化的時候,將節點的父節點設為自身,size 設為 1。class union find object def init self,data list self.fathe...

python實現各種常用演算法之資料結構(8)

字典樹的主要性質 根節點不包含字元,除根節點外每乙個節點都只包含乙個字元 從根節點到某一節點,路徑上經過的字元連線起來,為該節點對應的字串 每個節點的所有子節點包含的字元都不相同。基本功能實現 建立乙個 trienode 的類,構建內建字典結構 class trienode def init sel...