首页 > 其他分享 >Golang实现hashmap

Golang实现hashmap

时间:2022-11-20 21:37:20浏览次数:39  
标签:node index hashmap nil 实现 Value Next Golang Data

golang实现hashmap

思路:数组+链表->HashMap

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

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

01

2 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"))
}

标签:node,index,hashmap,nil,实现,Value,Next,Golang,Data
From: https://www.cnblogs.com/JujunWang/p/16909593.html

相关文章

  • ping实现
    ping实现实现一#encoding:utf-8importtimeimportstructimportsocketimportselectimportsysdefchesksum(data):n=len(data)m=n%2sum=0......
  • golang接收文件脚本
    golang接收文件脚本packagemainimport("io""os""fmt""io/ioutil""net/http")//https://www.jianshu.com/p/b49cc19d26f0参考资料......
  • Dubbo-Activate实现原理
    前言在Dubbo中有Filter使用,对于Filter来说我们会遇到这样的问题,Filter自身有很多的实现,我们希望某种条件下使用A实现,另外情况下使用B实现,这个时候我们前面介绍@SPI和@Adap......
  • 基于close channel广播机制来实现TimingWheel
    代码packagemainimport( "fmt" "sync" "time")typeTimingWheelstruct{ sync.Mutex intervaltime.Duration ticker*time.Ticker quitchanstruct{......
  • Dockerfile基础实现
    Dockerfile实现1)Dockerfile概述我们目前都是手动拉取镜像,手动进行配置,手动安装依赖,手动编译安装,创建用户……这个过程类似于命令行使用ansible模块(繁琐,不方便重复执行......
  • socket模块实现网络编程及struct模块解决黏包问题
    目录一、socket模块1、简介2、基于文件类型的套接字家族3、基于网络类型的套接字家族二、socket代码简介三、socket代码优化1.聊天内容自定义2.让聊天循环起来3.用户输入的......
  • 十大排序算法的各种编程语言的实现
    排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排......
  • golang的编译过程
    编译过程:-----编译前端------词法分析与语法分析类型检查(别的语言中的语义分析,这时候有语法错误才会被找出来)-----编译后端------中间代码生成机器码生成我......
  • Kubernetes 1.25.4数据平面自带nginx负载均衡实现高可用
    1、环境准备要点:1、使用一个FQDN统一作为APIServer的接入点;2、加入集群之前,每个节点都将该FQDN解析至第一个Master;3、加入集群之后,每个Master节点将该FQDN都解析至自身......
  • 45.自定义函数实现分组统计
    #自定义函数实现分组统计#能过自定义的函数实现分组统计importpandasaspddf=pd.read_excel('电脑配件销售记录.xlsx')#print(df.head()))#回顾知识点#p......