複習一下常見的數據結構與算法
文章目錄
一、走進哈希表(hashTable)
1.哈希表的目的
實現數據的快速查找
2.哈希表的設計原理
二、哈希表的設計要素
- 哈希函數-hash function
- 衝突解決方案-collision solution
- 重哈希-rehashing
1.哈希函數-hash function
基本概念
一個哈希函數需要具備如下特徵:
- 確定性
- 不可逆
其輸入爲: 任意二進制數據,輸出爲:整數(Buckets的位置)
優秀的哈希函數
如何評價一個哈希函數是否優秀了?這裏我們主要看:
- 儘可能少的發生碰撞
- 計算複雜度不要太高
常見的哈希函數包括:
- 除餘法modulo division
- 平方取中法 mid square
- 基數轉換法 radix transformation
Java中字符串的hash函數
實現邏輯:
for(char c : str){
hashCode = 31 * hashCode + c;
}
所以在Aa,BB、Ab,BC時會出現碰撞。通過如下測試代碼可以發現,他們的hashCode是相同的。
System.out.println("Aa".hashCode());
System.out.println("BB".hashCode());
2.衝突解決方案-collision solution
開散列
open hashing, 又稱拉鍊法 separate chaining
一言以蔽之,每個Bucket放的都是一個鏈表頭結點的引用,假如衝突了就在這個鏈表後面加一個結點即可。(鏈表,往下拉)
閉散列
closed hashing,又稱開址法 open addressing
當前位置已有其他元素後,再通過新算法爲其找新的位置,(如這個位置的下一個空位).
(有哪些常見的查找新位置的算法呢?線性探查,待補充!)
3.重哈希-rehashing
哈希表擴縮容時,需要對已有數據的位置進行重新編排,這個就是常說的重哈希。
負載因子
負載因子load factor,等於哈希表元素的個數/哈希表容量,用於描述哈希表當前的負載。
一般當負載因子大於0.5的時候,檢索性能急劇下降,衝突概率變高,此時一般就要進行哈希表擴容與重哈希了。
重哈希的描述
- 調整哈希表的大小,並將元素重新擺放。
- 當哈希表過於稀疏,進行重哈希可以節省空間
- 當哈希表過於稠密,進行哈希可以加速查找( 空間換時間)