日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2021-10-20 哈希表 恋上数据结构笔记

發(fā)布時間:2025/3/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021-10-20 哈希表 恋上数据结构笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 引入:TreeMap的局限性
  • 哈希表概念
  • 哈希沖突 以及JDK1.8的哈希沖突是如何解決的
  • 哈希函數(shù)
  • 不同數(shù)據(jù)類型對應的哈希函數(shù)
    • int 和 float
    • long 和 double
    • 字符串的哈希值計算
    • 關于自定義對象的哈希值計算方法
    • 區(qū)分Key與哈希值與索引與Value!!!


引入:TreeMap的局限性


哈希表概念

如下:說實話第一次看到這個,直接用Key值當索數(shù)組引,我尋思這不就一大型數(shù)組嗎,確實是做到了添加刪除搜索全部O1,但是也真是浪費了很多空間

看到后面,哦,原來上面是開玩笑的,哈希表通過引入哈希函數(shù)的概念,解決了浪費空間的問題,哈希函數(shù)就是通過Key值通過函數(shù)計算這個元素在數(shù)組中的真實索引,這樣就可以做到既是數(shù)組存儲,又一個Key對應一個數(shù)組元素,并不浪費空間


哈希沖突 以及JDK1.8的哈希沖突是如何解決的

如圖

JDK1.8使用鏈地址法解決哈希沖突,在添加元素時,計算索引,若索引處已經(jīng)有一個或多個元素,則比較新添加元素的Key與索引處元素鏈表里的Key,比較直到鏈表尾部,若Key不重合則直接在鏈表尾部添加。所以自然不用雙向鏈表


哈希函數(shù)

就是計算哈希值的函數(shù)
哈希函數(shù)通過Key計算數(shù)組內(nèi)的索引,所以要求計算出來的索引一定是要在數(shù)組的最大長度以內(nèi)的,所以下面的%運算和與(&&)運算都可以做到,最后計算出來的結果在數(shù)組長度以內(nèi),但是與運算對于計算機而言效率更高


不同數(shù)據(jù)類型對應的哈希函數(shù)

int 和 float

如下圖為 int 類型和 float類型的哈希函數(shù)
在選擇哈希函數(shù)時,要盡量遵守兩個原則:

  • 盡量讓生成的哈希值彼此唯一
  • 盡量讓Key的所有信息參與運算生成哈希值
  • long 和 double

    long和double屬于轉換成二進制屬于64位,而java中規(guī)定hash函數(shù)的返回值只能是一個32位的int值,所以這兩位的哈希函數(shù)要通過64位的計算,生成一個32位的哈希值

    小尖尖是亦或運算,二者相同則為1,二者相反則為0
    就是先把long和double轉換成64位二進制表達,然后取前32位和后32位進行亦或運算,生成一個32位的哈希值,這樣64位就都參與生成了哈希值。

    字符串的哈希值計算

    字符串的哈希值就是用類似把二進制轉換成十進制的過程,每個字符×31的位數(shù)減一次冪,加上后面的字符同樣如此,其中字符在運算過程中被轉換成為對應的ASCII碼

    為什么是31呢,這是一個數(shù)學問題,我們只需要知道i×31可以表達為位運算左移5位在減去i就可以了,位運算效率比較高,而java內(nèi)部也確實是這么轉化的,關于為什么是31可以看下面這張更具體

    關于自定義對象的哈希值計算方法

    默認自定義對象在的哈希函數(shù)的參數(shù)是 對象實體的地址 ,也就是說哈希值是通過地址計算出來的。
    但這導致了一個問題,兩個內(nèi)容相同的對象因為地址不同,而在哈希表中被視為兩個不同的元素,想要解決這個問題就需要自己重寫一個hashcode函數(shù),重寫的函數(shù)計算方法類似字符串,是每個元素的哈希值*31的n次冪加起來的和:如下圖
    同時又導致了一個問題,就是如果對象插入時索引處已經(jīng)有了元素,這時候就要在索引處單鏈表進行比較,比較已經(jīng)有的元素與插入的元素Key是否相同,而官方的比較方法是比較地址,這樣就會造成索引處有可能存儲兩個內(nèi)容相同但是地址不同的自定義對象,為了解決這個問題,我們可以自己寫一個對象比較equal函數(shù)
    只有同時自己實現(xiàn)了hashCode函數(shù)與equal函數(shù),才能保證哈希表中不會存儲兩個內(nèi)容相同但地址不同的自定義對象Key。

    只重寫equal函數(shù),會導致

    區(qū)分Key與哈希值與索引與Value!!!

    學著學著總把這三個搞混,Key是一個對象,對應一個value,一個Key只能對應一個哈希值和一個索引,而一個哈希值或一個索引可能對應多個key和value,哈希值是哈希函數(shù)通過Key計算出來的值,盡力做到一個Key對應一個哈希值,但依然有可能給多個Key計算出來哈希值一樣,而索引=哈希值%哈希表長度,也就是數(shù)組中的真實下標。

    總結

    以上是生活随笔為你收集整理的2021-10-20 哈希表 恋上数据结构笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。