Go的数据结构与实现【HashMap】

介绍

哈希表数据结构由哈希函数实现。数据结构不是使用自定义键将Key存储在映射中,而是对键执行散列函数以返回数组中Value的确切索引。

实现

实现思路

哈希表主要使用Go的map数据结构来实现,提供以下方法:

  • Put()
  • Remove()
  • Get()
  • Size()
    这里实现的哈希表并没有考虑哈希冲突,哈希函数采用著名的Horner’s method。
// the hash() private function uses the famous Horner's method
// to generate a hash of a string with O(n) complexity
func hash(k Key) int {
   h := 0
   for i := 0; i < len(k); i++ {
      h = 31*h + int(k[i])
   }
   return h
}

向哈希表中添加或删除元素即计算哈希映射然后刚刚map中k-v值,关于哈希冲突的解决后续有机会再去实现。

import "sync"

type Key string
type Value string

type HashMap struct {
   sync.RWMutex
   hashmap map[int]Value
}

func NewHashMap() *HashMap {
   ret := &HashMap{hashmap: make(map[int]Value)}

   return ret
}

// Put item with value v and key k into the hashmap
func (h *HashMap) Put(k Key, v Value) {
   h.Lock()
   defer h.Unlock()

   i := hash(k)
   if h.hashmap == nil {
      h.hashmap = make(map[int]Value)
   }

   h.hashmap[i] = v
}

// Remove item with key k from hashmap
func (h *HashMap) Remove(k Key) bool {
   h.Lock()
   defer h.Unlock()

   i := hash(k)
   if _, ok := h.hashmap[i]; ok {
      delete(h.hashmap, i)
      return true
   }

   return false
}

// Get item with key k from the hashmap
func (h *HashMap) Get(k Key) *Value {
   h.RLock()
   defer h.RUnlock()

   i := hash(k)
   if v, ok := h.hashmap[i]; ok {
      return &v
   }
   return nil
}

// Size returns the number of the hashmap elements
func (h *HashMap) Size() int {
   h.RLock()
   defer h.RUnlock()

   return len(h.hashmap)
}

单元测试

import "testing"

func TestHash(t *testing.T) {
   var key Key = "testKey"
   hashKey := hash(key)
   if hashKey != 105951707245 {
      t.Errorf("wrong hash, expect 105951707245 but got %d", hashKey)
   }
}

var (
   k1 Key   = "key1"
   k2 Key   = "key2"
   k3 Key   = "key3"
   v1 Value = "value1"
   v2 Value = "value2"
   v3 Value = "value3"
)

func InitHashMap() *HashMap {
   hashmap := NewHashMap()
   hashmap.hashmap[hash(k1)] = v1
   hashmap.hashmap[hash(k2)] = v2

   return hashmap
}

func TestHashMap_Put(t *testing.T) {
   hashmap := InitHashMap()
   if size := hashmap.Size(); size != 2 {
      t.Errorf("wrong count, expected 2 and got %d", size)
   }

   v := hashmap.Get(k3)
   if v != nil {
      t.Errorf("key k3 is not in hashmap")
   }

   hashmap.Put(k3, v3)
   if size := hashmap.Size(); size != 3 {
      t.Errorf("wrong count, expected 3 and got %d", size)
   }
   v = hashmap.Get(k3)
   if *v != v3 {
      t.Errorf("key k3 is in hashmap")
   }
}

func TestHashMap_Remove(t *testing.T) {
   hashmap := InitHashMap()

   ret := hashmap.Remove(k1)
   if !ret {
      t.Errorf("removing key k1 should return true")
   }

   ret = hashmap.Remove(k3)
   if ret {
      t.Errorf("removing key k1 should return false")
   }
}

相关推荐

  1. Go数据结构实现HashMap

    2024-03-31 07:28:06       21 阅读
  2. Go数据结构实现【LinkedList】

    2024-03-31 07:28:06       18 阅读
  3. Go数据结构实现【Graph】

    2024-03-31 07:28:06       20 阅读
  4. HashMap底层结构

    2024-03-31 07:28:06       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-31 07:28:06       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-31 07:28:06       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-31 07:28:06       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-31 07:28:06       18 阅读

热门阅读

  1. go mod命令介绍

    2024-03-31 07:28:06       16 阅读
  2. Let`s move - sui move开发实战-dao(6)反馈

    2024-03-31 07:28:06       20 阅读
  3. math模块篇(七)

    2024-03-31 07:28:06       18 阅读
  4. 代码随想录算法训练营第三十四天|leetcode62、63题

    2024-03-31 07:28:06       17 阅读
  5. 【LeetCode热题100】【链表】LRU缓存

    2024-03-31 07:28:06       21 阅读
  6. 解析GPU:探索图形处理单元的奇妙世界

    2024-03-31 07:28:06       17 阅读
  7. CSS3 简介

    2024-03-31 07:28:06       15 阅读
  8. @RequestParam、@PathVariable、@RequestBody

    2024-03-31 07:28:06       13 阅读