散列表

散列表 又叫 哈希表 (hash table)。經過訪問key而直接訪問存儲的value值。它的key - value之間存在一個映射函數,咱們能夠經過key值和「看不到」的映射函數(散列函數)訪問對應的value值。這加快了查找的速度!存放記錄的數組稱作散列表。散列方法不一樣於順序查找、二分查找、二叉排序樹及B-樹上的查找。它不以關鍵字的比較爲基本操做,採用直接尋址技術 (就是說,它是直接經過key映射[映射函數,實現的方式有多種] 到內存地址上去的)。在理想狀況下,無須任何比較就能夠找到待查關鍵字,查找的指望時間爲O(1)(面試的時候犯了這個錯誤)。php

 

舉個形象的例子來講:爲了查找電話簿中某人的號碼,能夠建立一個按照人名首字母順序排列的表(即創建人名x到首字母F(x)的一個函數關係),在首字母爲W的表中查找「王」姓的電話號碼,顯然比直接查找就要快得多。這裏使用人名做爲關鍵字,「取首字母」是這個例子中散列函數的函數法則F(),存放首字母的表對應散列表。關鍵字和函數法則理論上能夠任意肯定。[維基百科]面試

 

散列表
     設全部可能出現的關鍵字集合記爲U(簡稱全集)。實際發生(即實際存儲)的關鍵字集合記爲K(|K|比|U|小得多)。
     散列方法是使用函數h將U映射到表T[0..m-1]的下標上(m=O(|U|))。這樣以U中關鍵字爲自變量,以h爲函數的運算結果就是相應結點的存儲地址。從而達到在O(1)時間內就可完成查找。
  其中:
     ① h:U→{0,1,2,…,m-1} ,一般稱h爲散列函數(Hash Function)。散列函數h的做用是壓縮待處理的下標範圍,使待處理的|U|個值減小到m個值,從而下降空間開銷。
     ② T爲散列表(Hash Table)。
     ③ h(Ki)(Ki∈U)是關鍵字爲Ki結點存儲地址(亦稱散列值或散列地址)。
     ④ 將結點按其關鍵字的散列地址存儲到散列表中的過程稱爲散列(Hashing)
數組

咱們基本知道了value和key之間存在一個映射關係h,簡單的表示爲 value = h(key)。 咱們會有疑問,函數以容許多對一出現的,也就是說,當多個key對應一個value時怎麼辦?安全

這就是散列表中的衝突。分佈式

散列表的衝突現象
(1)衝突
     兩個不一樣的關鍵字,因爲散列函數值相同,於是被映射到同一表位置上。該現象稱爲衝突(Collision)或碰撞。發生衝突的兩個關鍵字稱爲該散列函數的同義詞(Synonym)。
   【例】上圖中的k2≠k5,但h(k2)=h(k5),故k2和K5所在的結點的存儲地址相同。

(2)安全避免衝突的條件
     最理想的解決衝突的方法是安全避免衝突。要作到這一點必須知足兩個條件:
①其一是|U|≤m
其二是選擇合適的散列函數
     這隻適用於|U|較小,且關鍵字均事先已知的狀況,此時通過精心設計散列函數h有可能徹底避免衝突。

(3)衝突不可能徹底避免
     一般狀況下,h是一個壓縮映像。雖然|K|≤m,但|U|>m,故不管怎樣設計h,也不可能徹底避免衝突。所以,只能在設計h時儘量使衝突最少。同時還須要肯定解決衝突的方法,使發生衝突的同義詞可以存儲到表中。

函數

構造散列函數spa

 

(直接複製的維基百科,詳細可參見[1]) 散列函數能使對一個數據序列的訪問過程更加迅速有效,經過散列函數,數據元素將被更快定位。設計

 

  1. 直接尋址法:取關鍵字或關鍵字的某個線性函數值爲散列地址。即hash(k)=khash(k)=a\cdot k + b,其中a\,b爲常數(這種散列函數叫作自身函數)
  2. 數字分析法:假設關鍵字是以r爲基的數,而且哈希表中可能出現的關鍵字都是事先知道的,則可取關鍵字的若干數位組成哈希地址。
  3. 平方取中法:取關鍵字平方後的中間幾位爲哈希地址。一般在選定哈希函數時不必定能知道關鍵字的所有狀況,取其中的哪幾位也不必定合適,而一個數平方後的中間幾位數和數的每一位都相關,由此使隨機分佈的關鍵字獲得的哈希地址也是隨機的。取的位數由表長決定。
  4. 摺疊法:將關鍵字分割成位數相同的幾部分(最後一部分的位數能夠不一樣),而後取這幾部分的疊加和(捨去進位)做爲哈希地址。
  5. 隨機數法
  6. 除留餘數法:取關鍵字被某個不大於散列表表長m的數p除後所得的餘數爲散列地址。即hash(k)=k \,\bmod \,pp\le m。不只能夠對關鍵字直接取模,也可在摺疊法平方取中法等運算以後取模。對p的選擇很重要,通常取素數或m,若p選擇很差,容易產生碰撞。

 

查找效率

散列表的查找過程基本上和造表過程相同。一些關鍵碼可經過散列函數轉換的地址直接找到,另外一些關鍵碼在散列函數獲得的地址上產生了衝突,須要按處理衝突的方法進行查找。在介紹的三種處理衝突的方法中,產生衝突後的查找仍然是給定值與關鍵碼進行比較的過程。因此,對散列表查找效率的量度,依然用平均查找長度來衡量。xml

查找過程當中,關鍵碼的比較次數,取決於產生衝突的多少,產生的衝突少,查找效率就高,產生的衝突多,查找效率就低。所以,影響產生衝突多少的因素,也就是影響查找效率的因素。影響產生衝突多少有如下三個因素:blog

  1. 散列函數是否均勻;
  2. 處理衝突的方法;
  3. 散列表的載荷因子(load factor)。

 

參考:【1】維基百科  散列表 http://zh.wikipedia.org/zh-cn/%E5%93%88%E5%B8%8C%E8%A1%A8 

   【2】維基百科  分佈式散列表 http://zh.wikipedia.org/zh-cn/%E5%88%86%E6%95%A3%E5%BC%8F%E9%9B%9C%E6%B9%8A%E8%A1%A8

相關文章
相關標籤/搜索