哈希表相关概念
參考:
https://www.cnblogs.com/songdechiu/p/6954038.html
https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/算法 - 符號表.md
1. 第一步是用哈希函數將鍵轉換為數組的一個索引,理想情況下不同的鍵都能轉換為不同的索引值,但是實際上會有多個鍵哈希到到相同索引值上。
因此,第二步就是處理碰撞沖突的過程。這里有兩種處理碰撞沖突的方法:separate chaining(拉鏈法)和linear probing(線性探測法)
哈希表是算法在時間和空間上做出權衡的經典例子。
如果沒有內存限制,算法可以直接將鍵作為數組(可能是超級大)的索引,那么所有的查找操作只需要訪問一次內存即可完成。但這種理想情況一般不會出現,因為當鍵很多時,需要的內存太大。
如果沒有時間限制,算法可以使用無序數組并進行順序查找,這樣只需要很少的內存。
哈希表使用了適度的空間和時間并在這兩種極端之間找到了一種平衡。
一個優秀的哈希方法需要滿足三個條件:
一致性——等價的鍵必須產生相等的哈希值
高效性——計算簡便
均勻性——均勻地哈希所有鍵
假設
假設:算法使用的哈希函數能夠將所有鍵均勻并獨立地分布到0和M-1之間。
這個假設是實際上無法達到的理想模型,但是是算法實現哈希函數的指導思想。
三、基于拉鏈法的哈希表
1、簡介
哈希函數將鍵轉化為數組索引,第二步就是需要進行碰撞處理。
一種最直接的方法是將大小為M的數組的每個元素指向一條鏈表,鏈表的每個節點都儲存了哈希值為該位置數組下標的鍵值對。
這種方法稱為拉鏈法(separate chaining)。因為沖突的元素都放在同一個鏈表上。
這種方法的思想就是:選擇足夠大的M使得鏈表都盡可能短以保證高效查找。
查找順序:先根據哈希值找到相應的鏈表,然后遍歷鏈表查找相應的鍵。
四、基于線性探測法的哈希表
1、簡介
實現哈希表的另一種方法是用大小為M的數組保存N個鍵值對,其中M>N。這種方法依靠數組中的空位解決碰撞沖突。
當發生碰撞時,算法檢查下一個位置(將索引加1)。
這樣線性探測可能會產生三種結果:
命中,該位置的鍵和要查找的鍵相同。
未命中,該鍵為空。
繼續查找,該位置的鍵和要查找的鍵不相同。
和拉鏈法一樣,線性探測法哈希表的性能也依賴于N/M的比值。
只不過意義不一樣,這里是N/M是哈希表中被占用的空間比例,算法使用動態調整數組大小方法來保證使用率在1/8到1/2之間。
和拉鏈法一樣,動態調整數組大小需要重新哈希所有鍵。
詳細代碼實現請見 連接。
總結
- 上一篇: 栈与队列的实现
- 下一篇: 哈夫曼编码之大根堆小根堆揭西县