雜湊 雜湊法 LeetCode例題

2021-10-05 06:55:44 字數 1474 閱讀 7137

說到雜湊,總感覺到它很高深,說到底它只不過是實現集合和字典(滿足資料增刪改查的結構)的一種方式,而不是總把它當成單獨的一種資料結構或者演算法去討論。

定義:將資料中key傳給乙個雜湊函式f(),按照計算出來的雜湊值h=f(key)將那個帶有key的資料分布到乙個雜湊表中(大小m自定義)。

當m《資料量n的時候,會出現碰撞(即雜湊值為同乙個,意味著雜湊值相同的資料要儲存在雜湊表的同乙個雜湊位址裡),甚至大於等於的時候也會出現(取決於雜湊函式),所以此時需要解決碰撞的機制。

解決碰撞1開雜湊:每個雜湊單元格都儲存著乙個鍊錶,所有對應雜湊值的資料都儲存在這個煉表裡,所以碰撞後,直接將相同雜湊值的資料依次往煉表裡push,所以可想而知最壞情況就是所有鍵的雜湊值都是一樣,這樣的話所有資料都在乙個雜湊位址的單元格煉表裡。這樣的話增刪改查都是遍歷對應那個雜湊值的鍊錶即可。

解決碰撞2閉雜湊:當碰撞時,對應雜湊值的單元格已經儲存資料,這時我們就線性探測(往這個單元格後面依次遍歷,只要找到乙個空的就將元素插在裡面),這種方法比前一種更有可能出現最壞情況:會導致合併的雜湊單元格越來越多,到最後可能插入乙個元素就需要o(n),因為可能需要遍歷很多單元格才能找到空的。往雜湊表裡新增是這樣,查詢也是如此,依次往後找(但是如果雜湊合併了就很麻煩了),刪除更加麻煩,因為刪除了以後查詢某個鍵,就不會往後找,直接就不存在了,所以我們就需要在刪除時新增個佔位符,表示曾經有過資料,但是被刪除了。而且閉雜湊有的時候防止最壞情況的發生,需要輔助雙雜湊或者重雜湊。個人還是選擇開散吧。

雜湊法對資料的操作為o(1)~o(n)(最壞情況),假如選擇適當的雜湊函式和雜湊表的大小基本上為o(1),實現集合/字典降低了操作的時間複雜度。

與另一種實現字典的資料結構平衡二叉搜尋樹相比:

時間複雜度的不同:雜湊平均為o(1),最壞為o(n),而平衡二叉搜尋樹最好最壞都是o(logn)

有序性保留:雜湊不保留key有序性,而後者保留,所以雜湊表不適合按序遍歷和按範圍查詢的應用。

例題:

#define mp make_pair

class

solution;}

else

hash_table.

insert(mp

(nums[i]

,i));}

return ans;}}

;

class

solution

return hash_table.

size()

< nums.

size()

;}};

class

solution

int longest =0;

for(pair<

int,

int> t:hash_table)

}return longest;}}

;

雜湊衝突之雜湊法

雜湊碰撞 雜湊衝突 不同的key值經過雜湊函式hash key 處理以後可能產生相同的值雜湊位址,我們稱這種情況為雜湊衝突。任意的雜湊函式都不能避免產生衝突。閉雜湊法 線性探測 void insert1 int x pos if pos v.capacity s pos exist v pos x ...

雜湊拉鍊法(雜湊桶)

昨天寫了雜湊的開放定址法的部落格,今天我們要說的是拉鍊法,還有乙個名字叫雜湊桶。雜湊桶要做的就是,之前我們用的開放定址法,通過將資料對映到陣列中來實現雜湊。這裡每個陣列的位置只能存放乙個資料,如果衝突的話會繼續往下找找到空的位置然後放進去,但是其實大家都能感覺出來上乙個 很簡單,也很扯,感覺實現起來...

雜湊表(閉雜湊 拉鍊法 雜湊桶)

雜湊表,也稱雜湊表,是一種通過key值來直接訪問在記憶體中的儲存的資料結構。它通過乙個關鍵值的函式 被稱為雜湊函式 將所需的資料對映到表中的位置來訪問資料。關於雜湊表,主要為以下幾個方面 一 雜湊表的幾種方法 1 直接定址法 取關鍵字key的某個線性函式為雜湊位址,如hash key key 或 h...