package main
import (
"fmt"
)
// Entry holds a key-value pair and points to next entry in bucket
type Entry struct {
key string
value int
next *Entry
}
// HashMap holds buckets array
type HashMap struct {
buckets []*Entry
size int
}
// NewHashMap creates a hashmap with fixed bucket size
func NewHashMap(size int) *HashMap {
return &HashMap{
buckets: make([]*Entry, size),
size: size,
}
}
// hash function converts key string to bucket index
func (h *HashMap) hash(key string) int {
hash := 0
for _, ch := range key {
hash = (hash*31 + int(ch)) % h.size
}
return hash
}
// Put inserts or updates key-value pair
func (h *HashMap) Put(key string, value int) {
index := h.hash(key) // find bucket
current := h.buckets[index]
// traverse bucket to find key
for current != nil {
if current.key == key {
current.value = value // update existing
return
}
current = current.next
}
// insert new entry at bucket head
newEntry := &Entry{key: key, value: value, next: h.buckets[index]}
h.buckets[index] = newEntry
}
// Get returns value for key, or -1 if not found
func (h *HashMap) Get(key string) int {
index := h.hash(key) // find bucket
current := h.buckets[index]
// search bucket linked list
for current != nil {
if current.key == key {
return current.value
}
current = current.next
}
return -1 // not found
}
func main() {
hm := NewHashMap(5)
hm.Put("cat", 1)
hm.Put("dog", 2)
hm.Put("bird", 3)
fmt.Println(hm.Get("dog"))
}index := h.hash(key) // find bucket
compute bucket index from key
for current != nil { if current.key == key { current.value = value; return } current = current.next }
search bucket for existing key to update
newEntry := &Entry{key: key, value: value, next: h.buckets[index]}
create new entry and link it at bucket head
current := h.buckets[index]
start searching bucket linked list for get
for current != nil { if current.key == key { return current.value } current = current.next }
traverse bucket to find key and return value