Hash Tables (Maps)
Section 4: Hash Tables (Maps)
Penjelasan Konsep
Kompleksitas Operasi
Contoh Implementasi
package main
import "fmt"
// HashNode merepresentasikan node dalam chaining
type HashNode struct {
Key string
Value int
Next *HashNode
}
// HashMap adalah implementasi hash table dengan chaining
type HashMap struct {
buckets []*HashNode
size int
capacity int
}
// NewHashMap membuat hash map baru
func NewHashMap(capacity int) *HashMap {
return &HashMap{
buckets: make([]*HashNode, capacity),
size: 0,
capacity: capacity,
}
}
// hash function sederhana
// Kompleksitas Waktu: O(k) dimana k adalah panjang key
func (hm *HashMap) hash(key string) int {
hashValue := 0
for _, char := range key {
hashValue = (hashValue*31 + int(char)) % hm.capacity
}
return hashValue
}
// Put menambahkan atau update key-value pair
// Kompleksitas Waktu: O(1) average, O(n) worst case jika banyak collision
// Kompleksitas Ruang: O(1)
func (hm *HashMap) Put(key string, value int) {
index := hm.hash(key)
// Cek apakah key sudah ada (update case)
current := hm.buckets[index]
for current != nil {
if current.Key == key {
current.Value = value
return
}
current = current.Next
}
// Key belum ada, insert di awal chain (insert case)
newNode := &HashNode{
Key: key,
Value: value,
Next: hm.buckets[index],
}
hm.buckets[index] = newNode
hm.size++
}
// Get mengambil value berdasarkan key
// Kompleksitas Waktu: O(1) average, O(n) worst case
// Kompleksitas Ruang: O(1)
func (hm *HashMap) Get(key string) (int, bool) {
index := hm.hash(key)
current := hm.buckets[index]
for current != nil {
if current.Key == key {
return current.Value, true
}
current = current.Next
}
return 0, false
}
// Delete menghapus key-value pair
// Kompleksitas Waktu: O(1) average, O(n) worst case
// Kompleksitas Ruang: O(1)
func (hm *HashMap) Delete(key string) bool {
index := hm.hash(key)
// Kasus khusus: head adalah yang akan dihapus
if hm.buckets[index] != nil && hm.buckets[index].Key == key {
hm.buckets[index] = hm.buckets[index].Next
hm.size--
return true
}
// Traverse chain untuk mencari key
current := hm.buckets[index]
for current != nil && current.Next != nil {
if current.Next.Key == key {
current.Next = current.Next.Next
hm.size--
return true
}
current = current.Next
}
return false
}
// Size mengembalikan jumlah elemen
func (hm *HashMap) Size() int {
return hm.size
}
// LoadFactor menghitung rasio elemen terhadap bucket
func (hm *HashMap) LoadFactor() float64 {
return float64(hm.size) / float64(hm.capacity)
}Studi Kasus: Two Sum dengan Hash Map
Studi Kasus: LRU Cache
Penjelasan Kompleksitas LRU Cache
Last updated