Skip to content

Commit c7556a8

Browse files
committed
basic implementation of hashmap with linked list as storing the bucket
0 parents  commit c7556a8

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

map.go

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
//go:build ignore
2+
3+
package main
4+
5+
import "fmt"
6+
7+
const MAP_SIZE = 100
8+
9+
type HashTable[T any] struct {
10+
key string
11+
value T
12+
}
13+
14+
type Node[T any] struct {
15+
data HashTable[T]
16+
next *Node[T]
17+
}
18+
19+
type HashMap[T any] struct {
20+
arr [MAP_SIZE]*Node[T]
21+
size int
22+
}
23+
24+
func NewMap[T any]() *HashMap[T] {
25+
var items [MAP_SIZE]*Node[T]
26+
return &HashMap[T]{
27+
arr: items,
28+
size: 0,
29+
}
30+
}
31+
32+
func (m *HashMap[T]) Insert(k string, v T) {
33+
idx := ComputeHash(k) % MAP_SIZE
34+
node := &Node[T]{
35+
data: HashTable[T]{
36+
key: k,
37+
value: v,
38+
},
39+
next: m.arr[idx],
40+
}
41+
42+
m.arr[idx] = node
43+
m.size++
44+
}
45+
46+
func (m *HashMap[T]) Get(k string) *T {
47+
idx := ComputeHash(k) % MAP_SIZE
48+
curr := m.arr[idx]
49+
50+
for curr != nil {
51+
table := curr.data
52+
if table.key == k {
53+
return &table.value
54+
}
55+
56+
curr = curr.next
57+
}
58+
59+
return nil
60+
}
61+
62+
func (m *HashMap[T]) Delete(k string) bool {
63+
isDelete := false
64+
idx := ComputeHash(k) % MAP_SIZE
65+
curr := m.arr[idx]
66+
67+
if curr == nil {
68+
return false
69+
}
70+
71+
if curr.data.key == k {
72+
m.arr[idx] = curr.next
73+
m.size--
74+
return true
75+
}
76+
77+
for curr.next != nil {
78+
table := curr.next.data
79+
if table.key == k {
80+
// found the key, now remove it and shift all the later nodes towards it
81+
curr.next = curr.next.next
82+
m.size--
83+
return true
84+
}
85+
curr = curr.next
86+
}
87+
88+
return isDelete
89+
}
90+
91+
// modulo the hash result with the size of the array
92+
func ComputeHash(input string) uint {
93+
const p uint = 31
94+
const m uint = 1e9 + 9
95+
var hashValue uint = 0
96+
var pPow uint = 1
97+
for _, c := range input {
98+
hashValue = (hashValue + (uint(c)-uint('a')+1)*pPow) % m
99+
pPow = (pPow * p) % m
100+
}
101+
102+
return hashValue
103+
}
104+
105+
func main() {
106+
hashMap := NewMap[int]()
107+
hashMap.Insert("John", 18)
108+
hashMap.Insert("Abraham", 24)
109+
hashMap.Insert("Jack", 30)
110+
hashMap.Insert("Luis", 50)
111+
hashMap.Insert("Maple", 25)
112+
hashMap.Insert("Ron", 20)
113+
114+
john := hashMap.Get("John")
115+
if john == nil {
116+
fmt.Println("Key: `John` not found")
117+
} else {
118+
fmt.Printf("For John: %d\n", *john)
119+
}
120+
121+
abra := hashMap.Get("Abraham")
122+
if abra == nil {
123+
fmt.Println("Key: `Abraham` not found")
124+
} else {
125+
fmt.Printf("For Abraham: %d\n", *abra)
126+
}
127+
128+
luis := hashMap.Get("Luis")
129+
if luis == nil {
130+
fmt.Println("Key: `Luis` not found")
131+
} else {
132+
fmt.Printf("For Luis: %d\n", *luis)
133+
}
134+
135+
maple := hashMap.Get("Maple")
136+
if maple == nil {
137+
fmt.Println("Key: `Maple` not found")
138+
} else {
139+
fmt.Printf("For Maple: %d\n", *maple)
140+
}
141+
142+
rohn := hashMap.Get("Apple")
143+
if rohn == nil {
144+
fmt.Println("Key: `Apple` not found")
145+
} else {
146+
fmt.Printf("For Apple: %d\n", *rohn)
147+
}
148+
149+
status := hashMap.Delete("Jack")
150+
if !status {
151+
fmt.Println("Key not found, so unable to delete it")
152+
} else {
153+
// delete so not found in the table
154+
jack := hashMap.Get("Jack")
155+
if jack == nil {
156+
fmt.Println("Key: `Jack` not found")
157+
} else {
158+
fmt.Printf("For Jack: %d\n", *jack)
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)