算法小專欄:散列表(一)

級別: ★☆☆☆☆
標籤:「算法」「Hash」「散列表」「哈希表」
做者: MrLiuQ
審校: QiShare團隊php


本篇將介紹散列表哈希表)的相關基礎知識。html

1、簡介

散列表(Hash table,也叫哈希表)是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。 這個映射函數叫作散列函數,存放記錄的數組叫作散列表。(來源360百科)git

2、內部機制

2.1 散列函數:

散列函數:簡單來講是一個函數,傳入一個Key就返回一個固定的數。該數即爲散列表數組的下標。(用一句話描述:散列函數將「輸入」映射到「數字」。github

2.2 解決衝突:

對不一樣的關鍵字可能獲得同一散列地址,即k1≠k2,而f(k1)=f(k2),這種現象稱爲衝突(碰撞)。算法

常見的解決哈希衝突方案有如下四種:(詳細細節見下篇講解)數組

  • 開放定址法:爲產生衝突的地址H(key)求得一個新的地址序列: Hi =(H(key)+ di)% m (i=1,2,3,...,m-1) 其中H(key)爲哈希函數,m爲表長,di稱爲增量序列。(其中增量di的取值方法也有多種,詳細細節見下篇微信

  • 鏈地址法:將全部哈希地址相同的記錄都連接在同一鏈表中。數據結構

  • 再哈希法:產生衝突時計算**另外一個哈希函數(散列函數)**的地址,直到衝突再也不發生爲止。函數

  • 創建公共溢出區:把衝突的值都放在另外一個溢出表中,不把衝突的值存原表中。oop

3、性能對比

先介紹一個散列表的專有名詞:填裝因子負載因子)。

這裏列出了常見數據結構操做的時間複雜度。

/ 散列表(最佳狀況) 散列表(最壞狀況) 數組 鏈表
取值 O(1) O(n) O(1) O(n)
插入 O(1) O(n) O(n) O(1)
刪除 O(1) O(n) O(n) O(1)

能夠看出散列表在最佳狀況下的性能是很出色的,雖然最壞狀況的性能很差,但咱們能夠經過一些手段避免掉最壞狀況。所以,散列表的最優狀況就是平均狀況,時間複雜度爲常數級O(1)。

所以,散列表在使用中須要注意兩點:

  • 較低的填裝因子(或稱負載因子)。(建議:高於0.7時,考慮散列表翻倍擴容)
  • 優秀的散列函數。(儘可能減小衝突的發生)

PS:Python的作法是,會設法保證大概還有三分之一的表元是空的,當快要達到這個閥值的時候,會進行擴容,將原散列表複製到一個更大的散列表裏。

4、應用實例

例如,用散列表實現一個電話薄。

主要功能以下:

  • 加入聯繫人及電話號碼。
  • 經過查找對應名稱首字母,獲得全部該首字母名稱的聯繫人。

圖解以下:

代碼以下:

# 建立一個telBook的散列表
telBook = dict()

# 將A-Z的字母做爲telBook的Key,Value仍是一個散列表
for ch in xrange(0x41, 0x5A):
    telBook[unichr(ch)] = dict()

# 將聯繫人加入telBook中,取首字母做爲第一個Key,名稱做爲第二個Key,電話做爲第二個Key的Value。
def addFriend(name, phoneNumber):
    telBook[name[0:1]][name] = phoneNumber

addFriend("QiShare1", 13800000000)
addFriend("QiShare2", 13811111111)
addFriend("QiShare3", 13822222222)
addFriend("QiShare4", 13833333333)
addFriend("QiShare5", 13844444444)
addFriend("QiShare6", 13855555555)
addFriend("Police", 110)
addFriend("XiaoMing1", 1)
addFriend("XiaoMing2", 2)
addFriend("XiaoMing3", 3)

# 輸出結果:
for ch in xrange(0x41, 0x5A):
    if telBook[unichr(ch)]:
        print unichr(ch)+":"
        print telBook[unichr(ch)]
複製代碼

打印結果以下:


小編微信:可加並拉入《QiShare技術交流羣》。

關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)

推薦文章:
iOS UIButton根據內容自動佈局
iOS 指定初始化方法
UIView中的hitTest方法
iOS關於tabBar的幾處筆記
A的女兒是B的女兒的媽媽,A是B的誰?
算法小專欄:選擇排序
iOS Runloop(一)
奇舞週刊

相關文章
相關標籤/搜索