采用拉链法(前插法)解决冲突
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
}
}