首頁 >後端開發 >Golang >golang怎麼實作hashmap

golang怎麼實作hashmap

PHPz
PHPz原創
2023-04-03 09:14:421156瀏覽

golang語言自帶的map結構是一種非常方便的資料類型,但對於需要更有效率、更靈活的資料操作,我們可以選擇使用golang實作的hashmap。本文將介紹golang實作hashmap的方法。

一、實作原理

golang實作hashmap的原理很簡單,就是透過一定的演算法將鍵值對映射到一個陣列中,並且使用鍊錶解決哈希衝突。具體來說,實作hashmap需要以下幾個步驟:

  1. 建立一個數組,數組大小為2的n次方(n可調整)。
  2. 計算每個要插入的鍵值對的雜湊值,然後用雜湊值對數組大小進行取模以獲得其在數組中的位置。
  3. 如果該位置為空,則直接將鍵值對插入陣列中該位置的鍊錶中。
  4. 如果該位置已經有值,則遍歷該位置的鍊錶,判斷是否存在相同的鍵,若存在,則更新其對應的值;若不存在,則直接將該節點插入鍊錶末端。
  5. 尋找鍵值對時,先透過雜湊值對數組大小進行取模得到其在數組中的位置,然後遍歷該位置的鍊錶查找對應鍵的值。

二、實作程式碼

下面是一個簡單的golang實作hashmap的程式碼:

package hashmap

import "sync"

type Node struct {
    key   string
    value interface{}
    next  *Node
}

type HashMap struct {
    size  int
    nodes []*Node
    mutex sync.Mutex
}

func NewHashMap(size int) *HashMap {
    return &HashMap{size, make([]*Node, size), sync.Mutex{}}
}

func (hm *HashMap) hash(key string) int {
    h := 0
    for i := 0; i < len(key); i++ {
        h = (h << 5) + h + int(key[i])
    }
    return h % hm.size
}

func (hm *HashMap) Set(key string, value interface{}) {
    hm.mutex.Lock()
    defer hm.mutex.Unlock()
    i := hm.hash(key)
    if hm.nodes[i] == nil {
        hm.nodes[i] = &Node{key, value, nil}
    } else {
        for n := hm.nodes[i]; n != nil; n = n.next {
            if n.key == key {
                n.value = value
                return
            }
            if n.next == nil {
                n.next = &Node{key, value, nil}
                break
            }
        }
    }
}

func (hm *HashMap) Get(key string) interface{} {
    hm.mutex.Lock()
    defer hm.mutex.Unlock()
    i := hm.hash(key)
    for n := hm.nodes[i]; n != nil; n = n.next {
        if n.key == key {
            return n.value
        }
    }
    return nil
}

func (hm *HashMap) Delete(key string) {
    hm.mutex.Lock()
    defer hm.mutex.Unlock()
    i := hm.hash(key)
    if hm.nodes[i] != nil {
        if hm.nodes[i].key == key {
            hm.nodes[i] = hm.nodes[i].next
            return
        }
        for n := hm.nodes[i]; n.next != nil; n = n.next {
            if n.next.key == key {
                n.next = n.next.next
                return
            }
        }
    }
}

三、使用範例

使用範例如下:

package main

import (
    "fmt"
    "hashmap"
)

func main() {
    m := hashmap.NewHashMap(16)
    m.Set("apple", 1)
    m.Set("banana", 2)
    m.Set("cat", 3)
    fmt.Println(m.Get("apple"))   // Output: 1
    fmt.Println(m.Get("carrot")) // Output: <nil>
    m.Delete("banana")
    fmt.Println(m.Get("banana")) // Output: <nil>
}

四、總結

透過golang實現hashmap可以方便地進行高效、靈活的資料操作。實作hashmap的原理很簡單,主要是透過哈希演算法將鍵值對映射到一個陣列中,並使用鍊錶解決哈希衝突。使用範例中的程式碼可以供您參考,也可以根據自己的需求進行最佳化和改進。

以上是golang怎麼實作hashmap的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn