【Go】Go语言实现哈希表

采用拉链法(前插法)解决冲突

package hashtable

import "fmt"

type HashTable interface {
	Get(int) (int, bool)
	Put(int, int)
	Delete(int)
	Traverse()
}
type Node struct {
	Key, Value int
	Next       *Node
}
type SimpleHash struct {
	BasicArr []*Node // 底层数组
	Count    int     // 元素个数
	Len      int     // 底层数组长度
}

var _ HashTable = &SimpleHash{}
// 新建hashtable
func NewSimpleHash(len int) *SimpleHash {
	return &SimpleHash{
		BasicArr: make([]*Node, len),
		Len:      len,
		Count:    0,
	}
}
// 获取value
func (h *SimpleHash) Get(key int) (int, bool) {
	node, exist := h.get(key)
	value := 0
	if exist {
		value = node.Value
	}
	return value, exist
}
// 放置key-value
func (h *SimpleHash) Put(key, value int) {
	node, isExist := h.get(key)
	// key已经存在
	if isExist {
		node.Value = value
		return
	}
	// 不存在时,新建一个
	h.Count++
	idx := key % h.Len
	head := h.BasicArr[idx] // 第一个节点
	newNode := &Node{Key: key, Value: value}
	if head != nil {
		newNode.Next = head
	}
	h.BasicArr[idx] = newNode
}
// 删除key
func (h *SimpleHash) Delete(key int) {
	_, isExist := h.get(key)
	// 不存在
	if !isExist {
		return
	}
	// 存在则删除
	h.Count-- // 节点数量减一
	idx := key % h.Len
	head := h.BasicArr[idx]
	if head.Key == key { // 第一个节点就是要删除的节点
		h.BasicArr[idx] = head.Next
		return
	}
	for head.Next != nil { // 后续节点查找
		next := head.Next
		if next.Key == key {
			head.Next = next.Next
			return
		}
		head = head.Next
	}
}
// 遍历hashtable
func (h *SimpleHash) Traverse() {
	for _, head := range h.BasicArr {
		traveList(head)
	}
}
func (h *SimpleHash) get(key int) (*Node, bool) {
	exist := false
	// 获取链表头节点
	idx := key % h.Len
	head := h.BasicArr[idx]
	// 查找
	for head != nil {
		if head.Key == key {
			exist = true
			break
		}
		head = head.Next
	}
	return head, exist
}
// 遍历链表
func traveList(head *Node) {
	if head == nil {
		return
	}
	for head != nil {
		if head.Next == nil {
			fmt.Printf("%v-->%v\n", head.Key, head.Value)
			return
		}
		fmt.Printf("%v-->%v ", head.Key, head.Value)
		head = head.Next
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值