[資料結構]Hash Table — 雜湊表
在理解 hash table 之前,先來理解 hash(雜湊)吧!
雜湊的特色有以下幾點:
無論原本的內容長短,經過雜湊演算法處理過的值都會是固定長度
經由雜湊處理過的資料無法反推出原本的輸入為何
兩個輸入的內容即使只差一個字, 算出來的結果會會相差非常多
常用的雜湊演算法有 MD5 和 SHA ,後者的安全性更高
生活中的例子
1.保存用戶密碼
假如小明在 A 網站的登入密碼是 12345 ,存在後端資料庫的密碼通常會經過雜湊處理,不會大喇喇地把明碼 12345 存進去,因此就算駭客侵入資料庫, 也無法推測出原本的密碼是多少,確保資料安全性,所以如果有天你在某個網站點了忘記密碼,就會把原密碼原封不動寄到信箱裡的話 ,那就要特別小心了,那個網站可能會有資安疑慮。
2.檔案驗證
假如我們打開終端機輸入 md5 檔名 ,就會發現生成一組雜湊值,可以用來驗證兩個檔案是否一樣
什麼?雜湊不等於加密嗎?
- 加密需要有一把鑰匙, 透過鑰匙才能解密回推取得原本的內容
- 雜湊不需要鑰匙 ,無且無法回推原本的內容是甚麼
Hash Table
Hash table 中文叫作雜湊表,又被稱為關聯式陣列,是根據 key 來查詢資料存在哪個記憶體位置的資料結構,而這個 key 是透過 hash function(雜湊函數)計算出來的,搜尋速度為 O(1)。
buckets 是儲存資料的格子
HashMap Collision
經過 hash function 算出一個索引值,但可能會發生兩組資料算出來的索引值為重複的情形,這就是 HashMap Collision(碰撞),假如真的發生碰撞的話,就把碰撞的值放到同一個陣列裡或者是用 linked list 解決碰撞的問題,以下圖為例, Danny 和 Ella 的 id 經過 hash funciton 計算後的索引值都是 4,就會發生碰撞,所以這個時候我們可以設計成每個儲存格都是一個陣列,這樣的話遇到碰撞的值還是可以存放在同一個索引值底下。
用 js 實作 hash table
- hash1 的 function 為 Division Method,公式為 index = key mod size, 簡單來說就是 key(id)取 size(6)的餘數
- hash2 的 function 為 Multiplication Method,公式為 A =(√5–1)/2 , index = [m(keyA%1)],相信這邊應該已經蠻多人眼神死了,想要瞭解完整的公式解釋可以 google Multiplication Method
在無法預先得知「Key的範圍」以及「在該範圍內Key的分佈情形」之下,使 Multiplication Method 會比較好,所以採取 hash2 來做雜湊處理
1 | class HashTable { |
呼叫 printAll 可以發現印出來的 hash table 雖然有發生碰撞的情況,但還是可以看到碰撞的兩個物件安然無恙的放在同一個索引值底下 🎉
參考資料:Hashing 基礎介紹