哈希是什么?为什么哈希存取比较快?
不太恰當(dāng)?shù)谋扔?#xff1a;
XM 指的是“小明”,也指的是“小萌”
XM就是哈希值,小明和小萌就是擁有同一個(gè)哈希值的,存在同一個(gè)鏈表的元素。
想要獲取小萌,首先使用hashcode獲取到這兩個(gè)人,然后再通過(guò)equals獲取到小萌。
個(gè)人理解
哈希表其實(shí)就是一個(gè)一維數(shù)組,而數(shù)組中的每一個(gè)元素都是一個(gè)單向鏈表而已。這樣的數(shù)據(jù)結(jié)構(gòu)解決了數(shù)組的增刪元素的不足和鏈表的查詢效率的不足。
數(shù)組是存在連續(xù)的存儲(chǔ)空間,而鏈表的存儲(chǔ)空間不連續(xù)
--------------------------------
哈希算法將任意長(zhǎng)度的二進(jìn)制值映射為固定長(zhǎng)度的較小二進(jìn)制值,這個(gè)小的二進(jìn)制值稱為哈希值。哈希值是一段數(shù)據(jù)唯一且極其緊湊的數(shù)值表示形式。如果散列一段明文而且哪怕只更改該段落的一個(gè)字母,隨后的哈希都將產(chǎn)生不同的值。要找到散列為同一個(gè)值的兩個(gè)不同的輸入,在計(jì)算上是不可能的,所以數(shù)據(jù)的哈希值可以檢驗(yàn)數(shù)據(jù)的完整性。
哈希表是根據(jù)設(shè)定的哈希函數(shù)H(key)和處理沖突方法將一組關(guān)鍵字映象到一個(gè)有限的地址區(qū)間上,并以關(guān)鍵字在地址區(qū)間中的象作為記錄在表中的存儲(chǔ)位置,這種表稱為哈希表或散列,所得存儲(chǔ)位置稱為哈希地址或散列地址。作為線性數(shù)據(jù)結(jié)構(gòu)與表格和隊(duì)列等相比,哈希表無(wú)疑是查找速度比較快的一種。
哈希通過(guò)將單向數(shù)學(xué)函數(shù)(有時(shí)稱為“哈希算法”)應(yīng)用到任意數(shù)量的數(shù)據(jù)所得到的固定大小的結(jié)果。如果輸入數(shù)據(jù)中有變化,則哈希也會(huì)發(fā)生變化。哈希可用于許多操作,包括身份驗(yàn)證和數(shù)字簽名。也稱為“消息摘要”。
--------------------------------
原來(lái)hash是一個(gè)短的key值,來(lái)代替原有的對(duì)象,這樣查詢的效率就會(huì)高非常多的倍數(shù)。
也可以用在通信方面,比如兩個(gè)系統(tǒng)有相同的hash函數(shù),這樣就不需要傳遞大的對(duì)象,只需要傳遞hash值給對(duì)方,然后,對(duì)方在根據(jù)hash函數(shù)本地計(jì)算出對(duì)象。
覺(jué)得很棒。
--------------------------------
哈希算法存取之所以快,是因?yàn)槠?直接通過(guò)關(guān)鍵字key得到要存取的記錄內(nèi)存存儲(chǔ)位置
試想這樣的場(chǎng)景,你很想學(xué)太極拳,聽(tīng)說(shuō)學(xué)校有個(gè)叫張三豐的人打得特別好,于是你到學(xué)校學(xué)生處找人,學(xué)生處的工作人員可能會(huì)拿出學(xué)生名單,一個(gè)一個(gè)的查找,最終告訴你,學(xué)校沒(méi)這個(gè)人,并說(shuō)張三豐幾百年前就已經(jīng)在武當(dāng)山作古了。可如果你找對(duì)了人,比如在操場(chǎng)上找那些愛(ài)運(yùn)動(dòng)的同學(xué),人家會(huì)告訴你,"哦,你找張三豐呀,有有有,我?guī)闳?。于是他把你帶到了體育館內(nèi),并告訴你,那個(gè)教大家打太極的小伙子就是張三豐',原來(lái)"張三豐.是因?yàn)樗珮O拳打得好而得到的外號(hào)。學(xué)生處的老師找張三豐,那就是順序表查找,依賴的是姓名關(guān)鍵字的比較。而通過(guò)愛(ài)好運(yùn)動(dòng)的同學(xué)詢問(wèn)時(shí),沒(méi)有遍歷,沒(méi)有比較,就憑他們"欲找太極'張三豐',必在體育館當(dāng)中"的經(jīng)驗(yàn),直接告訴你位置。
也就是說(shuō),我們只需要通過(guò)某個(gè)函數(shù)f,使得
存儲(chǔ)位置=f (關(guān)鍵字)
那樣我們可以通過(guò)查找關(guān)鍵字不需要比較就可獲得需要的記錄的存儲(chǔ)位置。這就是一種新的存儲(chǔ)技術(shù)一一散列技術(shù)(哈希算法)。
散列技術(shù)是在記錄的存儲(chǔ)位置和它的關(guān)鍵字之間建立一個(gè)確定的對(duì)應(yīng)關(guān)系f,使得每個(gè)關(guān)鍵字key 對(duì)應(yīng)一個(gè)存儲(chǔ)位置f (key)。查找時(shí),根據(jù)這個(gè)確定的對(duì)應(yīng)關(guān)系找到給定值key 的映射f (key) ,若查找集合中存在這個(gè)記錄,則必定在f (key) 的位置上。
這里我們把這種對(duì)應(yīng)關(guān)系f 稱為散列函數(shù), 又稱為哈希(Hash) 函數(shù)。按這個(gè)思想,采用散列技術(shù)將記錄存儲(chǔ)在一塊連續(xù)的存儲(chǔ)空間中,這塊連續(xù)存儲(chǔ)空間稱為散列表或哈希表(Hash table)。 那么關(guān)鍵字對(duì)應(yīng)的記錄存儲(chǔ)位置我們稱為散列地址。
散列表是個(gè)一維數(shù)組,是連續(xù)的,而散列地址是不連續(xù)的
整個(gè)散列過(guò)程其實(shí)就是兩步。
(1) 在存儲(chǔ)時(shí),通過(guò)散列函數(shù)計(jì)算記錄的散列地址,并按此散列地址存儲(chǔ)該記錄。
(2) 當(dāng)查找記錄時(shí),我們通過(guò)同樣的散列函數(shù)計(jì)算記錄的散列地址,按此散列地址訪問(wèn)該記錄。由于存取用的是同一個(gè)散列函數(shù), 因此結(jié)果當(dāng)然也是相同的。
所以說(shuō),散列技術(shù)既是一種存儲(chǔ)方法,也是一種查找方法。然而它與線性表、樹(shù)、圖等結(jié)構(gòu)不同的是,前面幾種結(jié)構(gòu),數(shù)據(jù)元素之間都存在某種邏輯關(guān)系,可以用連線圖示表示出來(lái),而散列技術(shù)的記錄之間不存在什么邏輯關(guān)系,它只與關(guān)鍵字有關(guān)聯(lián)。因此,散列主要是面向查找的存儲(chǔ)結(jié)構(gòu)。
我們時(shí)常會(huì)碰到兩個(gè)關(guān)鍵字key1 != key2,但是卻有f(key1) = f(key2),這種現(xiàn)象我們稱為哈希沖突,如果沒(méi)有哈希沖突,散列表是一種非常高效的查找數(shù)據(jù)結(jié)構(gòu),其時(shí)間復(fù)雜度為O(1);
所以說(shuō),實(shí)際上哈希算法的時(shí)間復(fù)雜度并沒(méi)有O(1)
--------------------------------
為什么哈希存取比較快呢,很簡(jiǎn)單啦,因?yàn)橛蟹N算法叫做哈希算法,哈希算法會(huì)根據(jù)你要存入的數(shù)據(jù),先通過(guò)該算法,計(jì)算出一個(gè)地址值,這個(gè)地址值就是你需要存入到集合當(dāng)中的數(shù)據(jù)的位置,而不會(huì)像數(shù)組那樣一個(gè)個(gè)的進(jìn)行挨個(gè)存儲(chǔ),挨個(gè)遍歷一遍后面有空位就存這種情況了,而你查找的時(shí)候,也是根據(jù)這個(gè)哈希算法來(lái)的,將你的要查找的數(shù)據(jù)進(jìn)行計(jì)算,得出一個(gè)地址,這個(gè)地址會(huì)印射到集合當(dāng)中的位置,這樣就能夠直接到這個(gè)位置上去找了,而不需要像數(shù)組那樣,一個(gè)個(gè)遍歷,一個(gè)個(gè)對(duì)比去尋找,這樣自然增加了速度,提高了效率了.
--------------------------------
因?yàn)楣J浅?shù)的時(shí)間復(fù)雜度啊,不管數(shù)據(jù)量是大還是小,只要用一個(gè)固定的算法算出哈希值就能直接找到結(jié)果。
--------------------------------
哈希是個(gè)人名,也是一個(gè)算法的名稱。
哈希算法是數(shù)據(jù)查找技術(shù)中最經(jīng)典的算法之一。
用哈希算法建立索引值,加快查詢速度。
--------------------------------
最最簡(jiǎn)單易懂的說(shuō)法就是,hash算法將你傳入的key運(yùn)算成一個(gè)地址值,類似指針那樣,指向內(nèi)存中的某塊區(qū)域,存的時(shí)候根據(jù)該地址值,將value存到這個(gè)地址值映射的內(nèi)存區(qū)域里,取得時(shí)候從key作hash運(yùn)算后得出的地址值所對(duì)應(yīng)的內(nèi)存區(qū)域中取出結(jié)果;
--------------------------------
自己的理解:哈希一般是基于數(shù)組的,只要知道數(shù)組的下表,就可以很快的存取該元素。
通過(guò)對(duì)元素的一個(gè)關(guān)鍵字,在通過(guò)一個(gè)函數(shù),把這個(gè)關(guān)鍵字轉(zhuǎn)換成數(shù)組的下標(biāo),這個(gè)函數(shù)就是哈希函數(shù)。
這樣,就能通過(guò)關(guān)鍵字很快的存取元素。
有時(shí)候會(huì)發(fā)生沖突現(xiàn)象,即不同的關(guān)鍵字,通過(guò)哈希函數(shù)算出的結(jié)果是一樣的,這時(shí)候就可以用線性探測(cè)或者連地址法等來(lái)解決。
在使用哈希的時(shí)候,要考慮你存的數(shù)據(jù)個(gè)數(shù)的大小,然后再確定數(shù)組的大小,一般數(shù)組的大小是數(shù)據(jù)個(gè)數(shù)的兩倍(好像)。具體為什么就不是特別清楚了。。。。
--------------------------------
你好,哈希存儲(chǔ)基于一種映射關(guān)系的存儲(chǔ),實(shí)現(xiàn)這種映射關(guān)系的是哈希函數(shù)H(key)(這個(gè)函數(shù)按一定的標(biāo)準(zhǔn)可以自己設(shè)定),由節(jié)點(diǎn)的關(guān)鍵碼key值決定節(jié)點(diǎn)的存儲(chǔ)地址,然后直接由key值存儲(chǔ)或查找數(shù)據(jù),查找數(shù)據(jù)的時(shí)間復(fù)雜度為O(1)。所以查找的速度非常飛,畢竟時(shí)間復(fù)雜度為O(n),順序存儲(chǔ)查找的時(shí)間復(fù)雜度為O(n)。
--------------------------------
參考CSDN博客
總結(jié)
以上是生活随笔為你收集整理的哈希是什么?为什么哈希存取比较快?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 整理了一下目前的专栏文章,基本可以完整解
- 下一篇: Java中动态获取项目根目录和tomca