數(shù)據(jù)結(jié)構(gòu)之「哈希表」

什么是哈希表冈在?

哈希表(Hash table, 也叫散列表)醒陆,是根據(jù)鍵(Key)來直接訪問在內(nèi)存存儲位置的數(shù)據(jù)結(jié)構(gòu)宴凉。它通過一個哈希函數(shù)將所需要查詢的數(shù)據(jù)映射到一張哈希表中稍刀,來提升查詢效率帐萎。
哈希函數(shù)的實現(xiàn)方法:
1.除留余數(shù)法
取關(guān)鍵字被某個不大于哈希表表長的數(shù)除后所得的余數(shù)為散列地址比伏。
2.折疊法
將關(guān)鍵字分割成位數(shù)相同的幾部分(最后一部分的位數(shù)可以不同),然后取這幾部分的疊加和(舍去進(jìn)位)作為哈希地址疆导。
3.平方取中法
取關(guān)鍵字平方后的中間幾位為哈希地址赁项。
4.直接定址法
取關(guān)鍵字或關(guān)鍵字的某個線性函數(shù)值為哈希地址。

哈希沖突

不管用什么哈希函數(shù)去計算哈希地址澈段,都是會產(chǎn)生哈希沖突的悠菜,因此我們需要想辦法解決哈希沖突,并且在設(shè)計哈希函數(shù)時败富,盡可能減少哈希沖突李剖。
1.單獨的鏈表法
在哈希表的后面單獨鏈上一個單鏈表來存儲沖突的元素,JDK 1.8 里的 HashMap 就是選擇的這種方式解決沖突的囤耳,不過它對鏈表做了一層優(yōu)化篙顺。當(dāng)元素個數(shù)大于等于 8 時,會把鏈表轉(zhuǎn)換成紅黑樹充择,提升查詢效率德玫。
2.線性探測法
當(dāng)發(fā)生哈希沖突時,逐個探測存放地址的表椎麦,直到查找到一個空單元宰僧。這個方式不便于查找,不建議使用观挎。
3.建立一個公共溢出區(qū)
當(dāng)發(fā)生哈希沖突時琴儿,就把元素存入到公用的溢出區(qū)段化,查詢時遍歷溢出區(qū)。
從上面這幾種處理方法來說造成,還是鏈表法效率比較高显熏,推薦使用。不過都有現(xiàn)成的工具類使用晒屎,因此只需要知道實現(xiàn)原理喘蟆,最好自己可以去寫代碼實現(xiàn)它。


哈希表

哈希表有什么用鼓鲁?

哈希表在日常開發(fā)中還是比較常用的蕴轨,因為它最優(yōu)的查詢時間復(fù)雜度是 O(1),當(dāng)哈希沖突比較嚴(yán)重的時候骇吭,查詢效率就相當(dāng)于線性的橙弱,因此哈希算法直接影響到查詢的效率。

哈希表怎么實現(xiàn)的燥狰?

哈希表的結(jié)構(gòu)

public class HashMap<K,V> {
    //用節(jié)點數(shù)組當(dāng)作哈希表
    Node<K,V>[] table;
    int size;
    //節(jié)點
    static class Node<K,V> {
        //哈希值
        final int hash;
        //鍵
        final K key;
        //值
        V value;
        //哈希值沖突時存儲
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }
}

總結(jié)

哈希表是一個鍵值對的存儲結(jié)構(gòu)棘脐,并且根據(jù)鍵進(jìn)行哈希算法找到對應(yīng)的存儲位置。哈希算法會直接影響到哈希表的查詢效率碾局,一般選擇哈希沖突小的實現(xiàn)方式荆残,以便提升查詢效率。當(dāng)哈希沖突時净当,一般選擇鏈表來存儲沖突的元素内斯,當(dāng)沖突的元素增多時,可以采用紅黑樹來存儲像啼,以提升查詢效率俘闯。JDK 1.8 版本的 HashMap,當(dāng)鏈表個數(shù)大于等于 8 時忽冻,就是采用紅黑樹來存儲的真朗。在知道元素個數(shù)時,初始化哈希表時直接指定哈希表大小僧诚,因為當(dāng)元素達(dá)到哈希表大小時遮婶,會做 resize 操作。當(dāng)元素越來越多時湖笨,resize 是很耗時的旗扑,相當(dāng)于重建哈希表。因此直接指定哈希表大小慈省,減少 resize 次數(shù)以便提升插入性能臀防。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子袱衷,更是在濱河造成了極大的恐慌捎废,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件致燥,死亡現(xiàn)場離奇詭異登疗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)篡悟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門谜叹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匾寝,“玉大人搬葬,你說我怎么就攤上這事⊙藁冢” “怎么了急凰?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長猜年。 經(jīng)常有香客問我抡锈,道長,這世上最難降的妖魔是什么乔外? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任床三,我火速辦了婚禮,結(jié)果婚禮上杨幼,老公的妹妹穿的比我還像新娘撇簿。我一直安慰自己,他們只是感情好差购,可當(dāng)我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布四瘫。 她就那樣靜靜地躺著,像睡著了一般欲逃。 火紅的嫁衣襯著肌膚如雪找蜜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天稳析,我揣著相機(jī)與錄音洗做,去河邊找鬼。 笑死彰居,一個胖子當(dāng)著我的面吹牛诚纸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裕菠,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼咬清,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起旧烧,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤影钉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掘剪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體平委,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年夺谁,在試婚紗的時候發(fā)現(xiàn)自己被綠了廉赔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡匾鸥,死狀恐怖蜡塌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情勿负,我是刑警寧澤馏艾,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站奴愉,受9級特大地震影響琅摩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锭硼,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一房资、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧檀头,春花似錦轰异、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蒋荚,卻和暖如春戳稽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背期升。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工惊奇, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人播赁。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓颂郎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親容为。 傳聞我的和親對象是個殘疾皇子乓序,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容