python演算法與資料結構 07查詢

2021-10-06 13:40:56 字數 4091 閱讀 1086

1.遞迴版本

def

binarysearch1

(alist,item)

:# 二分查詢前提:有序陣列

#二分查詢遞迴版本 時間複雜度:o(logn)

n =len(alist)if0

== n:

return

false

mid = n //

2if alist[mid]

== item:

return

true

elif alist[mid]

< item:

return binarysearch1(alist[mid+1:

],item)

#+1容易忘記

else

:return binarysearch1(alist[

:mid]

,item)

if __name__ ==

"__main__"

: li =[3

,13,34

,56,76

,83,99

,104

,677

]print

(li)

a = binarysearch1(li,

235)

print

(a)

2. 非遞迴版本
def

binarysearch2

(alist,item)

:#二分查詢前提:有序陣列

#二分查詢非遞迴版本 時間複雜度:o(logn)

n =len(alist)

start =

0 end = n -

1while start <= end:

mid =

(start + end)//2

if alist[mid]

== item:

return

true

elif alist[mid]

< item:

start = mid +

1else

: end = mid -

1return

false

if __name__ ==

"__main__"

: li =[3

,13,34

,56,76

,83,99

,104

,677

]print

(li)

a = binarysearch2(li,93)

print

(a)

性質:

常用於資料庫和作業系統的檔案系統的一種用於查詢的資料結構

m階的b+樹與b樹的主要差異:

b+樹b樹

具有n個關鍵字的節點只含有n棵子樹,即每個關鍵字對應一顆子樹

具有n個關鍵字的節點只含有n+1棵子樹

每個節點(非根內部節點)關鍵字個數n的範圍是⌈m/

2⌉⩽n

⩽m\lceil m / 2\rceil \leqslant n \leqslant m

⌈m/2⌉⩽

n⩽m (根節點1≤n

≤m1 \leq n \leq m

1≤n≤m)

每個節點(非根內部節點)關鍵字個數n的範圍是⌈m/

2⌉−1

⩽n⩽m

−1\lceil m / 2\rceil -1\leqslant n \leqslant m-1

⌈m/2⌉−

1⩽n⩽

m−1 (根節點1≤n

≤m−1

1 \leq n \leq m-1

1≤n≤m−

1)葉節點包含資訊,所有非葉節點僅起索引作用。非葉節點中的每個索引項只含有對應子樹的最大關鍵字和指向該子樹的指標,不含有該關鍵字對應記錄的儲存位址。

每個關鍵字對應乙個記錄的儲存位址

葉節點包含全部關鍵字,即在葉結點**現的關鍵字也會出現在葉結點中。

葉節點包含的關鍵字和其他節點包含的關鍵字是不重複的。

有乙個指標指向關鍵字最小的葉子節點,所有葉子節點連線成乙個單鏈表。

沒有基本概念:

雜湊表的英文叫「hash table」,我們平時也叫它「雜湊表」或者「hash表『』

雜湊錶用的是陣列支援按照下標隨機訪問資料的特性,所以雜湊表其實就是陣列的一種擴充套件,由陣列演化而來。可以說,如果沒有陣列,就沒有雜湊表。

理想情況下,對雜湊表進行查詢的時間複雜度是o(1),與元素個數無關。

雜湊函式設計的基本要求

雜湊函式計算得到的雜湊值是乙個非負整數;

如果key1 = key2,那hash(key1) == hash(key2);

如果key1 ≠ key2,那hash(key1) ≠ hash(key2)。

實際上第三點無法達到,因為無法避免雜湊衝突。

雜湊函式的構造方法

處理衝突的方法

1.開放定址法:

計算增量序列:

插入操作:

x經過hash演算法之後,被雜湊到位置下標為7的位置,但是這個位置已經有資料了,所以就產生了衝突。於是我們就順序地往後乙個乙個找,看有沒有空閒的位置,遍歷到尾部都沒有找到空閒的位置,於是我們再從表頭開始找,直到找到空閒位置2,於是將其插入到這個位置。

查詢操作:

在雜湊表中查詢元素的過程有點兒類似插入過程。我們通過雜湊函式求出要查詢元素的鍵值對應的雜湊值,然後比較陣列中下標為雜湊值的元素和要查詢的元素。如果相等,則說明就是我們要找的元素;否則就順序往後依次查詢。如果遍歷到陣列中的空閒位置,還沒有找到,就說明要查詢的元素並沒有在雜湊表中。

刪除操作:

對於使用線性探測法解決衝突的雜湊表,刪除操作稍微有些特別。不能單純地把要刪除的元素設定為空。在查詢的時候,通過線性探測方法找到乙個空閒位置,我們就可以認定雜湊表中不存在這個資料。但是,如果這個空閒位置是我們後來刪除的,就會導致原來的查詢演算法失效。本來存在的資料,會被認定為不存在。這個問題如何解決呢?

我們可以將刪除的元素,特殊標記為deleted。當線性探測查詢的時候,遇到標記為deleted的空間,並不是停下來,而是繼續往下探測。

開放定址法的缺點:不能隨意刪除元素

其他方法:

2.拉鍊法

在這裡插入描述

優點:拉鍊法適用於經常插入和刪除的情況。

插入的時間複雜度是o(1)。當查詢、刪除乙個元素時,我們同樣通過雜湊函式計算出對應的槽,然後遍歷鍊錶查詢或者刪除。那查詢或刪除操作的時間複雜度跟鍊錶的長度k成正比,也就是o(k)。對於雜湊比較均勻的雜湊函式來說,理論上講,k=n/m,其中n表示雜湊中資料的個數,m表示雜湊表中「槽」的個數。

對比:

基於鍊錶的雜湊衝突處理方法比較適合儲存大物件、大資料量的雜湊表,而且,比起開放定址法,它更加靈活,支援更多的優化策略,比如用紅黑樹代替鍊錶**。

雜湊查詢及效能分析:

裝載因子越大,說明空閒位置越少,衝突越多,雜湊表的效能會下降。

應用:

​ 遍歷 10 萬條資料,以 url 為 key,訪問次數為 value,存入雜湊表,同時記錄下訪問次數的最大值 k,時間複雜度 o(n)。

​ 如果 k 不是很大,可以使用桶排序,時間複雜度 o(n)。如果 k 非常大(比如大於 10 萬),就使用快速排序,複雜度 o(nlogn)。

參考:資料結構與演算法之美–王爭

王道考研演算法與資料結構

資料結構與演算法07 陣列

1 陣列是什麼 1 陣列是資料結構最基本結構,可以看成是線性表推廣。2 幾乎所有程式語言都把陣列設定成基礎固定的基礎變數型別。2 陣列結構 陣列在記憶體中是連續存放,並且儲存資料的記憶體也是連續的,可通過索引值直接訪問。3 陣列基本操作 由陣列的儲存結構可知,陣列具有查詢遍歷,增刪困難的特點。陣列新...

《資料結構與演算法之美》07 遞迴

一 如何理解 遞迴 遞迴是一種應用非常廣泛的演算法 或者程式設計技巧 二 遞迴的三個條件 1 乙個問題的解可以分解為幾個子問題的解 2 這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣 3 存在遞迴終止條件 三 如何編寫遞迴 寫遞迴 最關鍵的是 找到如何將大問題分解為小問題的規律,並且...

資料結構07

樹型結構 1 樹的基本概念 一種表示層次關係的 一對多 資料結構。有且僅有乙個特定的節點,該節點沒有前驅,被稱為根節點。剩餘的n個互不相交的子集,其中每個子集也都是一棵樹,被稱為根節點的子樹。注意 樹型結構具有遞迴性 樹中有樹 2 樹的表示方法 倒懸樹 巢狀法 凹凸法。3 樹的專業術語 節點 組成樹...