開放地址法散列

開放地址法

開放地址法是另一種(相對(duì)于分離鏈接法)解決散列沖突的方法。適用于裝填因子(散列表中元素個(gè)數(shù)和散列表長(zhǎng)度比)較小(小于0.5)的散列表。

開放地址法中索引的計(jì)算方法為$$h_{i}(x) = (Hash(X) + F(i)) % TableSize$$,其中:

  • Hash(x)為索引的計(jì)算方法
  • F(i)為沖突的解決函數(shù),有F(0) = 0,i為已經(jīng)嘗試計(jì)算索引的次數(shù)

F(i)一般有:

  • 線性探測(cè)法:$$F(i) = i$$,即每次沖突則向下尋找1個(gè)位置,直到找到不沖突的位置,容易產(chǎn)生“一次聚集”的現(xiàn)象(數(shù)據(jù)集中在某一個(gè)地址區(qū)域)
  • 平方探測(cè)法:$$F(i)=i^{2}$$,每次沖突按平方尋找下一個(gè)位置,直到找到不沖突的位置
  • 雙散列:$$F(i) = i\cdot hash_{2}(x)$$,即發(fā)生沖突后使用第二個(gè)散列函數(shù)計(jì)算下一個(gè)位置

代碼實(shí)現(xiàn)

數(shù)據(jù)結(jié)構(gòu)

結(jié)構(gòu)體

// 節(jié)點(diǎn)數(shù)據(jù)
type tableData struct {
    data int
}

// 節(jié)點(diǎn)
type tableNode struct {
    flag bool       //是否已經(jīng)插入數(shù)據(jù),用于沖突檢測(cè)
    key  string     //關(guān)鍵字
    data tableData  //節(jié)點(diǎn)數(shù)據(jù)
}

構(gòu)造函數(shù)

func newTableNode(key string, data tableData) *tableNode {
    return &tableNode{false, key, data}
}

散列表

結(jié)構(gòu)體

type hashTable struct {
    table  [17]tableNode
    length int
}

方法

計(jì)算散列值

func (h *hashTable) hashCompute(key string) int {
    hash := 0
    for i := range key {
        hash = hash + int(key[i])*32
    }
    return hash % h.length
}

插入方法

func (h *hashTable) insert(key string, data tableData) error {
    hash, i := h.hashCompute(key), 0
  
    // 若發(fā)生沖突,則搜索下一個(gè)位置 
    for i = 0; h.table[(i+hash)%h.length].flag != false && h.table[(i+hash)%h.length].key != key; i++ {
        if i == h.length {
            // 若找不到,則表滿,返回錯(cuò)誤
            return errors.New("table full")
        }
    }
    hash = (i + hash) % h.length
    
    // 插入數(shù)據(jù)
    h.table[hash].data = data
    h.table[hash].flag = true
    h.table[hash].key = key
    return nil
}

訪問方法

func (h *hashTable) visit(key string) (tableData, error) {
    hash := h.hashCompute(key)
    for index := 0; h.table[(index+hash)%h.length].flag == true; index++ {
        if h.table[(index+hash)%h.length].key == key {
            return h.table[(index+hash)%h.length].data, nil
        }
    }
    return tableData{}, errors.New("not find")
}

構(gòu)造函數(shù)

func newHashTable() *hashTable {
    data := &hashTable{}
    data.length = 17
    for i := range data.table {
        data.table[i] = *newTableNode("", tableData{})
    }
    return data
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 散列表,它是基于快速存取的角度設(shè)計(jì)的,也是一種典型的“空間換時(shí)間”的做法。顧名思義,該數(shù)據(jù)結(jié)構(gòu)可以理解為一個(gè)線性表...
    yeying12321閱讀 3,772評(píng)論 0 6
  • 為什么要設(shè)計(jì)散列這種數(shù)據(jù)結(jié)構(gòu)呢?在現(xiàn)實(shí)世界中,實(shí)體之間可能存在著映射關(guān)系(key-value),比如一個(gè)訂單可能對(duì)...
    yhthu閱讀 1,281評(píng)論 2 8
  • 參考資料 JavaScript高級(jí)程序設(shè)計(jì)(第3版) 一、理解對(duì)象 ( 一)對(duì)象屬性的分類 JS對(duì)象屬性有兩種類型...
    Evelyn_Chan閱讀 697評(píng)論 2 12
  • 莫言說,當(dāng)你的才華還撐不起你的野心的時(shí)候,你就應(yīng)該靜下心來學(xué)習(xí);當(dāng)你的能力還不能駕馭你的目標(biāo)時(shí),就應(yīng)該沉下心來歷練...
    煩人的昵稱閱讀 912評(píng)論 0 0
  • 一顆八卦心,一雙近視眼,我是八段錦。 前幾天,一個(gè)脾氣最好的同學(xué)問我:怎么才能讓孩子不玩手機(jī)?嘿,她算問對(duì)人了。 ...
    八段錦閱讀 14,912評(píng)論 12 22

友情鏈接更多精彩內(nèi)容