順序搜尋也稱為線性搜尋,屬於無序查詢演算法。
演算法原理
思路:複雜度分析從資料結構線性表的一端開始,順序掃瞄,依次將掃瞄到的結點關鍵字與給定值 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...