散列表入门
??? 學(xué)過(guò)編程語(yǔ)言的人,大多知道數(shù)組的概念,通過(guò)數(shù)組下標(biāo)就可以訪問(wèn)到數(shù)組的元素,這里數(shù)組的下標(biāo)是一種key,而此key的位置處存儲(chǔ)的是所謂的衛(wèi)星數(shù)據(jù)。我們希望能夠在O(1)的時(shí)間里訪問(wèn)到某個(gè)key標(biāo)識(shí)的衛(wèi)星數(shù)據(jù),數(shù)組在通常的情況下是一個(gè)不二的選擇,數(shù)組的這種尋址方法學(xué)術(shù)上叫做直接尋址法,如何稱之為“直接”呢?這里的直接指的是,依賴的key和存儲(chǔ)的key本質(zhì)上是一個(gè)東西,未經(jīng)過(guò)映射和轉(zhuǎn)換。那么如果key經(jīng)過(guò)映射和轉(zhuǎn)化,那么你已經(jīng)在做散列了,也就是Hash。
??? 開(kāi)發(fā)尋址法有明顯的限制,那就是key必須是整數(shù),而且如果key分布的域較大的時(shí)候,安排數(shù)組時(shí)可能會(huì)浪費(fèi)很大的地址空間。使用Hash能夠,通過(guò)映射函數(shù)將key,不管是何種類型的key,只要選擇合適的hash函數(shù),總能將key映射到一個(gè)和數(shù)據(jù)量相當(dāng)?shù)囊粋€(gè)范圍中,這樣在保持O(1)訪問(wèn)時(shí)間的同時(shí)也可以節(jié)省空間。但hash會(huì)碰到碰撞的問(wèn)題,何為碰撞?
??? 假設(shè)hash函數(shù)為y = h(k),如果兩個(gè)不同的key:k1, k2, 他們的h(k1) = h(k2)時(shí),就發(fā)生了碰撞。解決碰撞有兩種方法:第一個(gè)是鏈接法,第二個(gè)是開(kāi)放尋址法。
??? 鏈接法就是在hash處構(gòu)建一個(gè)鏈表,將所有的映射項(xiàng)都鏈接在相同的位置。
??? 開(kāi)放尋址法將hash函數(shù)進(jìn)行了擴(kuò)充,加入了一個(gè)探查序列:y = h(k, i), 構(gòu)建Hash表的時(shí)候,只要按照i的序列探查各個(gè)hash槽,如果為空則找到位置并插入,查找的時(shí)候也是按照同樣的探查序列進(jìn)行查找。
開(kāi)發(fā)尋址法的探查方法有三種:線性探查:h(k, i) = (hh(k) + i)mod m,? 二次探查:h(k, i) = (hh(k) + ai + bi^2) mod m
雙重散列:h(k, i) = (h1(k) + ih2(k)) mod m
?? 下面介紹幾個(gè)概念:
??? 隨機(jī)的選擇散列函數(shù)的散列叫作全域散列,全域散列函數(shù)是一個(gè)散列函數(shù)集。
?? 完全散列:在關(guān)鍵字集合靜態(tài)的情況下,最壞期望的訪問(wèn)時(shí)間為O(1)的散列叫做完全散列,通常采用二級(jí)的散列方案,每一級(jí)上都是一個(gè)全域散列。
轉(zhuǎn)載于:https://www.cnblogs.com/nirvana-phoenix/archive/2012/05/10/2493931.html
總結(jié)
- 上一篇: string[x]:size 属性具有无
- 下一篇: can1--can初探