Golang实现hashmap

golang实现hashmap

思路:数组+链表->HashMap

先看一下go里的map是怎么实现的

go实现map采用拉链法的实现,如下图所示,键值对中的键会经过一个哈希函数,哈希函数会帮我们找到一个桶,对应我们用数组加链表的实现方式,就是映射到数组数组的一个位置,若该位置已经有数据了,那么就会将数据添加到该位置的链表中。

01

HashMap实现

我的实现思路其实跟go的map实现思路类似,用数组+链表来模拟拉链法的实现。具体代码:

/**
*
* hashMap的golang实现
*
**/
 
package main
 
//桶的格子数
const BucketsCount = 20
 
//node节点
type Node struct {
	Next *Node
	Data Value
}
 
//node节点存放的实际对象
type Value struct {
	Key   string
	Value interface{}
}
 
//hashMap 桶
type HashMap struct {
	Buckets [BucketsCount]*Node //存在node节点的数组
}
 
//新建一个hashMap桶
func NewHashMap() HashMap {
	hashMap := HashMap{}
	for i := 0; i < BucketsCount; i++ {
		hashMap.Buckets[i] = NewEmptyNode()
	}
 
	return hashMap
}
 
//自定义hash算法获取key
func getBucketKey(key string) int {
	length := len(key)
	sum := 0
	for i := 0; i < length; i++ {
		sum = sum + int(key[i])
	}
	return sum % BucketsCount
}
 
//在hashMap桶中新加一个节点
func (h *HashMap) put(data Value) {
	//获取index
	index := getBucketKey(data.Key)
	node := h.Buckets[index]
	//判断数组节点是否是空节点
	if node.Data.Value == nil {
		node.Data = data
	} else {
		//发生了hash碰撞,往该槽的链表尾巴处添加存放该数据对象的新节点
		last := node
		for last.Next != nil {
			last = last.Next
		}
		newNode := &Node{Data: data, Next: nil}
		last.Next = newNode
	}
}
 
//从hashMap中获取某个key的值
func (h *HashMap) get(key string) interface{} {
	//获取index
	index := getBucketKey(key)
	if h.Buckets[index].Data.Key == key {
		return h.Buckets[index].Data.Value
	}
	if h.Buckets[index].Next == nil {
		return nil
	}
	next := h.Buckets[index].Next
	for {
		if next.Data.Key == key {
			return next.Data.Value
		}
		if next.Next == nil {
			return nil
		}
		next = next.Next
	}
	return nil
}
 
//创建一个空node
func NewEmptyNode() *Node {
	node := &Node{}
	node.Data.Key = ""
	node.Data.Value = nil
	node.Next = nil
	return node
}
 
func main() {
	myMap := NewHashMap()
	data1 := Value{"001", 1}
	myMap.put(data1)
	data2 := Value{"002", "this is string"}
	myMap.put(data2)
	fmt.Println(myMap.get("002"))
}
posted @ 2022-11-20 21:19  XiaojunW  阅读(220)  评论(0编辑  收藏  举报