哈希表

轉載自子醉君迷的博客,表示感謝
http://blog.csdn.net/u013752202/article/details/51104156

假設現在有1000個人的檔案資料需要存放進檔案櫃子裏。要求是能夠快速查詢到某人檔案是否已經存檔,如果已經存檔則能快速調出檔案。如果是你,你會怎麼做?

最普通的做法就是把每個人的檔案依次放到櫃子裏,然後櫃子外面貼上人名,需要查詢某個人的檔案的時候就根據這個人的姓名來確定是否已經存檔。但是1000個人最壞的情況下我們查找一個人的姓名就要對比1000次!並且人越多,最大查詢的次數也就越多,專業的說這種方法的時間複雜的就是O(n),意思就是人數增加n倍,那麼查詢的最大次數也就會增加n倍。這種方法,人數少的時候還好,人數越多查詢起來就越費勁。那麼有什麼更好的解決方法嗎?答案就是散列表算法,即哈希表算法。

哈希表算法

假設每個人的姓名筆劃數都是不重複的,那麼我們通過一個函數把要存檔的人姓名筆劃數轉換到1000以內,然後把這個人的資料就放在轉換後的數字指定的櫃子裏,這個函數就叫做哈希函數,按照這種方式存放的這1000個櫃子就叫哈系表(散列表),人名筆畫數就是哈系表的元素,轉換後的數就是人名筆劃數的哈希值(也就是櫃子的序號)。當要查詢某個人是否已經存檔的時候,我們就通過哈希函數把他的姓名筆劃數轉化成哈希值,如果哈希值在1000以內,那麼恭喜你這個人已經存檔,可以到哈希值指定的櫃子裏去調出他的檔案,否則這個人就是黑戶,沒有存檔!這就是哈希表算法了,是不是很方便,只要通過一次計算得出哈希值就可以查詢到結果了,專業的說法就是這種算法的時間複雜是O(1),即無論有多少人存檔,都可以通過一次計算得出查詢結果。

當然上面的只是很理想的情況,人名的筆劃數是不可能不重複的,轉換而來的哈希值也不會是唯一的。那麼怎麼辦呢?如果兩個人算出的哈希值是一樣的,難道把他們都放到一個櫃子裏面?如果1000個人得出的哈希值都是一樣的呢?

下面有幾種方法可以解決這種衝突。

拉鍊法(鏈地址法)

這種方法的做法是,如果計算得出的哈希值對應的櫃子裏面已經放了別人的檔案,那也不管了,就跟他的檔案放在一起。當然是按順序來存放。這樣下次來找的時候一個哈希值對應的櫃子裏面可能有很多人的檔案,最差的情況可能1000個人的檔案都在一個櫃子裏面!那麼時間複雜度又是O(n)了,跟普通的做法也沒啥區別了。在算法實現的時候,每個數組元素存放的不是內容而是鏈表頭,如果哈希值唯一,那麼鏈表大小爲1,否則鏈表大小爲重複的哈希值個數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章