Python演算法系列 雜湊演算法

2021-10-04 22:43:07 字數 3196 閱讀 6100

四、總結

雜湊演算法又稱雜湊函式演算法,是一種查詢演算法。就是把一些複雜的資料通過某種對映關係。對映成更容易查詢的方式,但這種對映關係可能會發生多個關鍵字對映到同一位址的現象,我們稱之為衝突。在這種情況下,我們需要對關鍵字進行二次或更多次處理。出這種情況外,雜湊演算法可以實現在常數時間內儲存和查詢這些關鍵字。

常見的資料查詢演算法:

順序查詢:是最簡單的查詢方法。需要對資料集中的逐個匹配。所以效率相對較低,不太適合大量資料的查詢問題。

二分法查詢:效率很高,但是要求資料必須有序。面對資料排序通常需要更多的時間。

深度優先和廣度優先演算法:對於大量的資料查詢問題,效率並不高。這個我們後面專門講解。

阿希查詢演算法:查詢速度快,查詢插入,刪除操作簡單等原因獲得廣泛的應用。

雜湊查詢的原理:根據數量預先設乙個長度為m的陣列。使用乙個雜湊函式f並以資料的關鍵字作為自變數得到唯一的返回值,返回值的範圍是0~m-1。這樣就可以利用雜湊函式f將資料元素對映到乙個陣列的某一位下標,並把資料存放在對應位置,查詢時利用雜湊函式f計算,該資料應存放在**,在相應的儲存位置取出查詢的資料。

這裡就有乙個問題:

關鍵字的取值在乙個很大的範圍,資料在通過雜湊函式進行對映時。很難找到乙個雜湊函式,使得這些關鍵字都能對映到唯一的值。就會出現多個關鍵字對映到同乙個值的現象,這種現象我們稱之為衝突。

哈西演算法衝突的解決方案有很多:鏈位址法,二次再雜湊法。線性探測再雜湊建立乙個公共溢位區

注意:鏈位址法本質是陣列+鍊錶的資料結構

鏈位址法儲存資料過程

首先建立乙個陣列雜湊儲存所有鍊錶的頭指標。由陣列的關鍵字key通過對應的雜湊函式計算出雜湊位址。找到相應的桶號之後,建立新的節點儲存該資料。並把節點放到桶內的鍊錶的最後面或者最前面。

鏈位址法查詢資料:由資料關鍵字通過雜湊。函式計算關鍵字對應的雜湊位址之後順序比較同類不節點。是否與所查到的關鍵字一樣,直到找到資料為止,如果全部節點都不和關鍵字一樣,則書名哈系表裡沒有該資料。解決了雜湊函式的衝突。

用鏈位址法構造的雜湊表插入和刪除節點操作易於實現,所以構造鍊錶的時間開銷很低。但是指標需要開闢額外的位址空間,當資料量很大時會擴大雜湊表規模,記憶體空間要求較大。

1.問題描述

要求在給定的一些數字中找出兩個數,使得它們的和為嗯,前提是這些資料中保證有答案,並且只有乙個答案。例如給3、4、5、7、10。從中選出兩個數字使它們的和為11,可以選擇4和7。

2.雙指標辦法解決

def

twosum

(nums,target)

: res =

#存放結果編號

newnumber = nums [:]

#將資料深拷貝乙份

newnumber.sort(

)#對拷貝結果排序

left =

0#定義左指標

right =

len(newnumber)-1

# 定義右指標

while left < right:

if newnumber[left]

+ newnumber[right]

==target:

#在原始陣列中第乙個元組尋找原始下標

for i in

range(0

,len

(nums)):

if nums[i]

== newnumber[left]

:#將下標結果接入集

break

for i in

range

(len

(nums)-1

,-1,

-1):

#向回找,尋找第二個元組

if nums[i]

== newnumber[right]

:break

res.sort(

)break

elif newnumber[left]

+newnumber[right]

< target:

left = left +

1else

: right = right -

1return

(res[0]

+1,res[1]

+1)s =twosum([3

,4,5

,7,10

],11)

print

('下標是:'

,s)

雙指標解決方案:

第一步:對資料進行排序

第二步:移動指標尋找答案

第三步:發現答案去原始資料中查詢這兩個元素的位置

顯然第一步和第三步很浪費時間,我們使用雜湊演算法,規避排序問題,直接查詢資料和下標的對應關係。

3.雜湊演算法求解

def

twosum

(nums,target)

:'''

這個函式只能解決兩個數字和,且答案有且僅有乙個的情況

'''dict

=for i in

range

(len

(nums)):

m = nums[i]

if target - m in

dict

:#判定target - m 是否在字典中

return

(dict

[target-m]+1

,i +1)

#存在返回連個數的下標

dict

[m]= i #若不存在則記錄鍵值對的值

s =twosum([3

,4,5

,7,10

],11)

print

('下標是:'

,s)

字典使用dict[key] = value 來記錄鍵值對的關係

演算法系列 5分鐘了解雜湊演算法

前言 雜湊演算法是現代密碼體系中的乙個重要組成部分。大家比較感興趣的數字貨幣,就使用了雜湊演算法。雜湊演算法簡介 雜湊 hash 演算法又稱為雜湊演算法,通過hash演算法,可以將任意長度的資訊轉換成乙個固定長度的二進位制資料,我們經常會使用十六進製制值來表示轉換後的資訊。比如,數字123,使用md...

手寫演算法系列(Python實現)

鍛鍊自己實現演算法的能力,k means演算法 k means演算法是一種常用的無監督聚類演算法,可以視作同時優化質心和每個樣本的標籤,使得損失函式最小,演算法執行過程提現了em的思想 import numpy as np import random class kmeans def init se...

java演算法系列

棧的概念 棧是一種特殊的線性表,堆疊的資料元素以及資料元素之間的關係和線性表是完全一樣的。差別是線性表是在任意位置進行插入和刪除操作,棧是只允許在固定的一端進行插入和刪除,棧的插入和刪除只允許在棧頂,棧的插入和刪除通常稱為進棧和出棧。資料集合 每個資料元素的資料型別可以是任意的型別 操作的集合 進棧...