golang hashmap

发布时间 2023-05-06 23:15:59作者: wallywl
package main

import (
    "fmt"
)

const HASH_BUCKET_SIZE = 3 //1023

type hash_node struct {
    key  interface{}
    val  interface{}
    next *hash_node
}

//hash bucket to save node address
var hash_bucket [HASH_BUCKET_SIZE]*hash_node

func hash(key interface{}) int {
    hash := 5381
    switch x := key.(type) {
    case string:
        // Time 33 hash
        for _, k := range x {
            hash += (hash << 5) + int(k)
        }

        return (hash % HASH_BUCKET_SIZE)

    case int:

        hash += (hash << 5) + x

        return (hash % HASH_BUCKET_SIZE)
    default:

        _ = x
        return 0
    }
}//insert new node addr in the head of linklist
func hash_insert(node *hash_node) {
    hash := hash(node.key)
    head := hash_bucket[hash]

    node.next = head
    hash_bucket[hash] = node
}

func key_cmp(a interface{}, b interface{}) bool {
    typ := fmt.Sprintf("%T", a)

    switch x := b.(type) {
    case string:
        if typ == "string" {
            if b == a {
                return true
            }
        }
    case int:
        if typ == "int" {
            if b == a {
                return true
            }
        }
    default:
        _ = x
        return false
    }

    return false
}

func hash_del(item *hash_node) bool {
    hash := hash(item.key)

    cur := hash_bucket[hash]
    if cur == nil {
        return false
    }

    if key_cmp(cur.key, item.key) {
        hash_bucket[hash] = cur.next
        return true
    }

    for node := cur.next; node != nil; node = node.next {
        if key_cmp(node.key, item.key) {

            cur.next = node.next

            return true
        }

        cur = node
    }

    return false
}

func hash_iterate() {
    for i := 0; i < HASH_BUCKET_SIZE; i++ {
        fmt.Printf("i %d ---------->  \n", i)
        for node := hash_bucket[i]; node != nil; node = node.next {
            fmt.Println(node.key, node.val)
        }
    }
}

func hash_get(key interface{}) interface{} {
    hash := hash(key)

    for node := hash_bucket[hash]; node != nil; node = node.next {

        if key_cmp(node.key, key) {
            return node.val
        }
    }

    return nil
}

func main() {

    for i := 0; i < 5; i++ {
        hash_insert(&hash_node{i, i + 1, nil})
        hash_insert(&hash_node{fmt.Sprintf("key%d", i), fmt.Sprintf("val%d", i+1), nil})
    }

    hash_iterate()

    fmt.Println("---------------after del------------")

    hash_del(&hash_node{"key4", nil, nil})

    hash_del(&hash_node{2, nil, nil})

    hash_iterate()

    fmt.Println(hash_get(4))
}

 output :

i 0 ---------->  

key3 val4

3 4

key0 val1

0 1

i 1 ---------->  

key4 val5

4 5

key1 val2

1 2

i 2 ---------->  

key2 val3

2 3

---------------after del------------

i 0 ---------->  

key3 val4

3 4

key0 val1

0 1

i 1 ---------->  

4 5

key1 val2

1 2

i 2 ---------->  

key2 val3

5

package main
import ("fmt")
const HASH_BUCKET_SIZE = 3 //1023
type hash_node struct {key  interface{}val  interface{}next *hash_node}
//hash bucket to save node addressvar hash_bucket [HASH_BUCKET_SIZE]*hash_node
func hash(key interface{}) int {hash := 5381switch x := key.(type) {case string:// Time 33 hashfor _, k := range x {hash += (hash << 5) + int(k)}
return (hash % HASH_BUCKET_SIZE)
case int:
hash += (hash << 5) + x
return (hash % HASH_BUCKET_SIZE)default:
_ = xreturn 0}}
func hash_init() {for i := 0; i < HASH_BUCKET_SIZE; i++ {}}
//insert new node addr in the head of linklistfunc hash_insert(node *hash_node) {hash := hash(node.key)head := hash_bucket[hash]
node.next = headhash_bucket[hash] = node}
func key_cmp(a interface{}, b interface{}) bool {typ := fmt.Sprintf("%T", a)
switch x := b.(type) {case string:if typ == "string" {if b == a {return true}}case int:if typ == "int" {if b == a {return true}}default:_ = xreturn false}
return false}
func hash_del(item *hash_node) bool {hash := hash(item.key)
cur := hash_bucket[hash]if cur == nil {return false}
if key_cmp(cur.key, item.key) {hash_bucket[hash] = cur.nextreturn true}
for node := cur.next; node != nil; node = node.next {if key_cmp(node.key, item.key) {
cur.next = node.next
return true}
cur = node}
return false}
func hash_iterate() {for i := 0; i < HASH_BUCKET_SIZE; i++ {fmt.Printf("i %d ---------->  \n", i)for node := hash_bucket[i]; node != nil; node = node.next {fmt.Println(node.key, node.val)}}}
func hash_get(key interface{}) interface{} {hash := hash(key)
for node := hash_bucket[hash]; node != nil; node = node.next {
if key_cmp(node.key, key) {return node.val}}
return nil}
func main() {
for i := 0; i < 5; i++ {hash_insert(&hash_node{i, i + 1, nil})hash_insert(&hash_node{fmt.Sprintf("key%d", i), fmt.Sprintf("val%d", i+1), nil})}
hash_iterate()
fmt.Println("---------------after del------------")
hash_del(&hash_node{"key4", nil, nil})
hash_del(&hash_node{2, nil, nil})
hash_iterate()
fmt.Println(hash_get(4))}