哈希表(Hash tables)
什麼是哈希表
在介紹哈希表的時候,先回顧一下前幾章的內容,再來比較下數組和鏈表的優缺點。
數組:尋址容易,但插入和刪除元素比較麻煩; 鏈表:插入和刪除元素容易,但尋址比較麻煩。數組
那麼有沒有一種數據結構是既能結合這兩種的優勢同時也能避免這兩種數據結構所帶來的缺點呢?答案是有的,那就是如今所講的哈希表。
哈希表又稱爲散列表,是根據關鍵碼值(Key,value)而直接進行訪問的數據結構。
它提供了快速的插入操做和查找操做,不管哈希表總中有多少條數據,
插入和查找的時間複雜度都是爲O(1)
複製代碼
以上是哈希表的定義,其結構示意圖以下所示:
從上述結構中我 最左邊的爲key,經過中間的哈希運算(hash function)從而造成一個有意義的數字下標數組,從而與右邊的value/buckets即元素內容造成了一個肯定的對應關係。
彷佛很難懂這三者(Keys,hash function,buckets)之間的關係,那麼就舉個例子🌰吧:👇👇👇
怎麼正確創建學號(Key)與Value之間的映射關係呢? 咱們能夠經過這樣的哈希運算 學號(key) - 201735020330
所得出的結果即做爲存放Value的數組中,好比這個池早香,她的學號是201735020336,經過咱們的哈希運算得數組下標值爲6,那麼咱們就能夠將其姓名和電話號碼放進這個下標值爲6的數組中。這樣一個簡單的哈希表就完成了。
❓ 哈希運算(hash funchion)有特定的運算方式嗎?
沒有,但爲了構造一個好的哈希函數:咱們但願hash函數做用在不一樣的key時,所獲得的value可以均勻的分佈在hash表中,即能儘量少的減小地址衝突
。比較常見的hash函數的構造方法有:
1)直接定址法 2)數字分析法3)平方取中 4)摺疊法5)除留餘數法
❓ 剛剛提到了地址衝突,什麼是地址衝突?
當你用hash函數做用在兩個互不相同的key上,獲得的value值相等。這就比如「下面有請王先生上臺演講」,但底下那麼多姓王的,不知道叫的是哪一個王先生,只好一塊兒上臺了。所以正如上面所說,好的哈希運算須要慎重考慮其運算方法,避免出現地址衝突。但萬一真的發生怎麼辦呢?一般有兩個辦法解決:
- 鏈地址法:
如圖所示,採用鏈表的辦法,將衝突的地址內容經過線性表的方式串聯起來,而後在這個地址裏經過順序檢索查找出咱們想要的值。
- 開放地址法:
其方法就是找到一個未被佔用地址的數組,並將元素存儲進去,尋找空地址的方法有不少,而上圖的方法就是較爲簡單線性查找法,從衝突的地址開始,往下搜索空地址。
爲何要用哈希表
1)索引速度快。2)方便數據的增刪改查
相比于于數組和鏈表,若是咱們以鏈表的方式依次查找,面對企業級的上千萬的數據是很是耗時耗內存的。而若是咱們使用數組的結構進行業務操做也會因刪除和插入而浪費不少時間。
哈希表簡單的實現