国产a国产片,无码欧美精品一区二区,国产在线观看无码免费视频,电家庭影院午夜

哈希表

「哈希表hash table」,又稱(chēng)「散列表」,其通過(guò)建立鍵key 與值value 之間的映射,實(shí)現(xiàn)高效的元素查詢。具
體而言,我們向哈希表輸入一個(gè)鍵key ,則可以在??(1) 時(shí)間內(nèi)獲取對(duì)應(yīng)的值value 。
如圖6?1 所示,給定?? 個(gè)學(xué)生,每個(gè)學(xué)生都有“姓名”和“學(xué)號(hào)”兩項(xiàng)數(shù)據(jù)。假如我們希望實(shí)現(xiàn)“輸入一個(gè)
學(xué)號(hào),返回對(duì)應(yīng)的姓名”的查詢功能,則可以采用圖6?1 所示的哈希表來(lái)實(shí)現(xiàn)。

除哈希表外,數(shù)組和鏈表也可以實(shí)現(xiàn)查詢功能,它們的效率對(duì)比如表6?1 所示。
? 添加元素:僅需將元素添加至數(shù)組(鏈表)的尾部即可,使用??(1) 時(shí)間。
? 查詢?cè)兀河捎跀?shù)組(鏈表)是亂序的,因此需要遍歷其中的所有元素,使用??(??) 時(shí)間。
? 刪除元素:需要先查詢到元素,再?gòu)臄?shù)組(鏈表)中刪除,使用??(??) 時(shí)間。
表6?1 元素查詢效率對(duì)比
數(shù)組鏈表哈希表
查找元素??(??) ??(??) ??(1)
添加元素??(1) ??(1) ??(1)
刪除元素??(??) ??(??) ??(1)
觀察發(fā)現(xiàn),在哈希表中進(jìn)行增刪查改的時(shí)間復(fù)雜度都是??(1) ,非常高效。

我們先考慮最簡(jiǎn)單的情況,僅用一個(gè)數(shù)組來(lái)實(shí)現(xiàn)哈希表。在哈希表中,我們將數(shù)組中的每個(gè)空位稱(chēng)為「桶
bucket」,每個(gè)桶可存儲(chǔ)一個(gè)鍵值對(duì)。因此,查詢操作就是找到key 對(duì)應(yīng)的桶,并在桶中獲取value 。
那么,如何基于key 來(lái)定位對(duì)應(yīng)的桶呢?這是通過(guò)「哈希函數(shù)hash function」實(shí)現(xiàn)的。哈希函數(shù)的作用是將
一個(gè)較大的輸入空間映射到一個(gè)較小的輸出空間。在哈希表中,輸入空間是所有key ,輸出空間是所有桶(數(shù)
組索引)。換句話說(shuō),輸入一個(gè)key ,我們可以通過(guò)哈希函數(shù)得到該key 對(duì)應(yīng)的鍵值對(duì)在數(shù)組中的存儲(chǔ)位置。
輸入一個(gè)key ,哈希函數(shù)的計(jì)算過(guò)程分為以下兩步。
1. 通過(guò)某種哈希算法hash() 計(jì)算得到哈希值。
2. 將哈希值對(duì)桶數(shù)量(數(shù)組長(zhǎng)度)capacity 取模,從而獲取該key 對(duì)應(yīng)的數(shù)組索引index 。
index = hash(key) % capacity
隨后,我們就可以利用index 在哈希表中訪問(wèn)對(duì)應(yīng)的桶,從而獲取value 。
設(shè)數(shù)組長(zhǎng)度capacity = 100、哈希算法hash(key) = key ,易得哈希函數(shù)為key % 100 。圖6?2 以key 學(xué)號(hào)
和value 姓名為例,展示了哈希函數(shù)的工作原理。

 



 

本質(zhì)上看,哈希函數(shù)的作用是將所有key 構(gòu)成的輸入空間映射到數(shù)組所有索引構(gòu)成的輸出空間,而輸入空間
往往遠(yuǎn)大于輸出空間。因此,理論上一定存在“多個(gè)輸入對(duì)應(yīng)相同輸出”的情況。
對(duì)于上述示例中的哈希函數(shù),當(dāng)輸入的key 后兩位相同時(shí),哈希函數(shù)的輸出結(jié)果也相同。例如,查詢學(xué)號(hào)為
12836 和20336 的兩個(gè)學(xué)生時(shí),我們得到:

類(lèi)似于數(shù)組擴(kuò)容,哈希表擴(kuò)容需將所有鍵值對(duì)從原哈希表遷移至新哈希表,非常耗時(shí)。并且由于哈希表容量
capacity 改變,我們需要通過(guò)哈希函數(shù)來(lái)重新計(jì)算所有鍵值對(duì)的存儲(chǔ)位置,這進(jìn)一步提高了擴(kuò)容過(guò)程的計(jì)算
開(kāi)銷(xiāo)。為此,編程語(yǔ)言通常會(huì)預(yù)留足夠大的哈希表容量,防止頻繁擴(kuò)容。
「負(fù)載因子load factor」是哈希表的一個(gè)重要概念,其定義為哈希表的元素?cái)?shù)量除以桶數(shù)量,用于衡量哈希
沖突的嚴(yán)重程度,也常被作為哈希表擴(kuò)容的觸發(fā)條件。例如在Java 中,當(dāng)負(fù)載因子超過(guò)0.75 時(shí),系統(tǒng)會(huì)將
哈希表容量擴(kuò)展為原先的2 倍。

 

通常情況下哈希函數(shù)的輸入空間遠(yuǎn)大于輸出空間,因此理論上哈希沖突是不可避免的。比如,輸
入空間為全體整數(shù),輸出空間為數(shù)組容量大小,則必然有多個(gè)整數(shù)映射至同一桶索引。
哈希沖突會(huì)導(dǎo)致查詢結(jié)果錯(cuò)誤,嚴(yán)重影響哈希表的可用性。為解決該問(wèn)題,我們可以每當(dāng)遇到哈希沖突時(shí)就
進(jìn)行哈希表擴(kuò)容,直至沖突消失為止。此方法簡(jiǎn)單粗暴且有效,但效率太低,因?yàn)楣1頂U(kuò)容需要進(jìn)行大量
的數(shù)據(jù)搬運(yùn)與哈希值計(jì)算。為了提升效率,我們可以采用以下策略。
1. 改良哈希表數(shù)據(jù)結(jié)構(gòu),使得哈希表可以在存在哈希沖突時(shí)正常工作。
2. 僅在必要時(shí),即當(dāng)哈希沖突比較嚴(yán)重時(shí),才執(zhí)行擴(kuò)容操作。
哈希表的結(jié)構(gòu)改良方法主要包括“鏈?zhǔn)降刂贰焙汀伴_(kāi)放尋址”。