散列

一般想法

理想的散列表數(shù)據(jù)結(jié)構(gòu)只不過是一個包含有關(guān)鍵字的具有固定大小的數(shù)組贞岭。

每個關(guān)鍵字被映射到從0~TableSize-1這個范圍中的某個數(shù)又憨,并且被放到合適的單元中袜炕。這個映射就叫做散列函數(shù)。理想情況下它應(yīng)該計(jì)算起來簡單献酗,并且應(yīng)該保證任何兩個不同的關(guān)鍵字映射到不同的單元寝受。不過這是不可能的,因?yàn)閱卧臄?shù)目是有限的罕偎,而關(guān)鍵字實(shí)際上是用不完的羡蛾。因此,我們尋找一個散列函數(shù)锨亏,該函數(shù)要在單元間均勻地分配關(guān)鍵字痴怨。

這就是散列的基本想法。剩下的問題就是要選擇一個函數(shù)器予,決定當(dāng)兩個關(guān)鍵字散列到同一個值的時候(這就叫做沖突)浪藻,應(yīng)該做什么以及如何確定散列表的大小。

散列函數(shù)(Hash函數(shù))

JDK中String的hashCode函數(shù):

    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;  // value即String的字符數(shù)組

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
散列函數(shù):允許溢出乾翔,增加了小于0的檢測

散列函數(shù)選擇完成之后爱葵,剩下的主要編程細(xì)節(jié)就是如何解決沖突的消除問題。如果當(dāng)一個元素被插入時與一個已經(jīng)插入的元素散列到相同的值反浓,那么就會產(chǎn)生一個沖突萌丈。解決這種沖突的方法有幾種,下面討論其中最簡單的兩種:分離鏈接法和開放定址法雷则。

分離鏈接法

其做法是將散列到同一個值的所有元素保留到一個表中辆雾。


分離鏈接法的實(shí)現(xiàn):


除鏈表外,很多方案都可以解決沖突現(xiàn)象:一顆二叉查找樹或者另一個散列表等都將勝任這個工作月劈。但是度迂,我們期望散列表是大的并且散列函數(shù)是好的,那么所有的鏈表都應(yīng)該是短的猜揪,從而任何復(fù)雜的嘗試就都不值得考慮了惭墓。

因?yàn)橐淮尾檎业臅r間是計(jì)算散列函數(shù)值(對應(yīng)數(shù)組下標(biāo))所需要的常數(shù)時間加上遍歷鏈表所用的時間,所以我們希望鏈表盡可能的短而姐。通過定義散列表的裝填因子以及適當(dāng)時候執(zhí)行rehash函數(shù)腊凶,可以保證鏈表盡可能的短。

我們定義散列表的裝填因子(load factor)為\lambda:散列表中元素的個數(shù)與該表大小的比拴念。分離鏈接法中的一般法則是使得表的大小與預(yù)料的元素個數(shù)大致相等(即讓\lambda \approx 1)钧萍。在上面的程序中,可以看出對應(yīng)的裝填因子大小為1:

  if(++currentSize > theLists.length)
      rehash();

如果裝填因子超過1丈莺,那么我們將調(diào)用rehash函數(shù)擴(kuò)大散列表的大谢蟆(即程序中數(shù)組的大小)缔俄。

不用鏈表的散列表(開放地址法)

線性探測法


平方探測法

雙散列

再散列(rehash)

分離鏈接表的再散列:

探測散列表的再散列:


標(biāo)準(zhǔn)庫中的散列表

HashMap的工作原理:
https://blog.csdn.net/suifeng629/article/details/82179996
https://zhuanlan.zhihu.com/p/28501879

ConcurrentHashMap底層實(shí)現(xiàn)原理:
http://www.reibang.com/p/865c813f2726

最壞情形下O(1)訪問的散列表

  • 完美散列
  • 布谷鳥散列
  • 跳房子散列
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弛秋,一起剝皮案震驚了整個濱河市器躏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蟹略,老刑警劉巖登失,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挖炬,居然都是意外死亡揽浙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門意敛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馅巷,“玉大人,你說我怎么就攤上這事草姻〉鲡” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵撩独,是天一觀的道長敞曹。 經(jīng)常有香客問我,道長综膀,這世上最難降的妖魔是什么澳迫? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮剧劝,結(jié)果婚禮上橄登,老公的妹妹穿的比我還像新娘。我一直安慰自己担平,他們只是感情好示绊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暂论,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拌禾。 梳的紋絲不亂的頭發(fā)上取胎,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音湃窍,去河邊找鬼闻蛀。 笑死,一個胖子當(dāng)著我的面吹牛您市,可吹牛的內(nèi)容都是我干的觉痛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼茵休,長吁一口氣:“原來是場噩夢啊……” “哼薪棒!你這毒婦竟也來了手蝎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤俐芯,失蹤者是張志新(化名)和其女友劉穎棵介,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吧史,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邮辽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了贸营。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吨述。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钞脂,靈堂內(nèi)的尸體忽然破棺而出锐极,到底是詐尸還是另有隱情,我是刑警寧澤芳肌,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布灵再,位于F島的核電站,受9級特大地震影響亿笤,放射性物質(zhì)發(fā)生泄漏翎迁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一净薛、第九天 我趴在偏房一處隱蔽的房頂上張望汪榔。 院中可真熱鬧,春花似錦肃拜、人聲如沸痴腌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽士聪。三九已至,卻和暖如春猛蔽,著一層夾襖步出監(jiān)牢的瞬間剥悟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工曼库, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留区岗,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓毁枯,卻偏偏與公主長得像慈缔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子种玛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355