原文链接

摘要: Golang map实现原理是hash
map(核心元素是桶,key通过哈希算法被归入不同的bucket中),key是无序的,很多应用场景可能需要map
key有序(例如交易所订单撮合),C++ 的stl map
实现了key有序,实际上是TreeMap是基于树(红黑树)的实现方式,即添加到一个有序列表,在O(log
n)的复杂度内通过key值找到value,优点是空间要求低,但在时间上不如HashMap。

有序Map实现方案

Golang map实现原理是hash map(核心元素是桶,key通过哈希算法被归入不同的bucket中),key是无序的,很多应用场景可能需要map key有序(例如交易所订单撮合),C++ 的stl map 实现了key有序,实际上是TreeMap是基于树(红黑树)的实现方式,即添加到一个有序列表,在O(log n)的复杂度内通过key值找到value,优点是空间要求低,但在时间上不如HashMap。

我的实现

闲来用go map + slice切片,实现了一套key有序map数据结构,就是空间换时间的玩法, 实质是map 负责存k v, slice负责维护k的有序索引位置(查找key采用的是二分法),实现后赠改删时间负责度是 O(log n) 。

如何优化

优化的一点思考:实际上主要就是在slice上维护k位置时的增改删费操作,这时候我们可根据具体应用在2分查找上下点文章。 例如可能所存的数据结构频繁操作的节点只有前面一部分,这时候我们可以加个逻辑,操作时slice时先2查找 slice子集(例如头部热点),这样可能很多增改删操作在第一时间就解决了,整体性能会有很大提升, 最好根据应用场景来具体分析解决。下面给出代码。

代码部分

Order_Map:

package Order_Mapfunc findIndexByBinarySearch(s []int, k int) (int, bool) {lo, hi := 0, len(s)var m intmax := len(s)if max == 0 {return 0, false}res := falsefor lo <= hi {m = (lo + hi) >> 1if m == 0 && s[0] > k {return 0, res}if m == max-1 && s[max-1] < k {return m + 1, res}if s[m] < k && s[m+1] > k {return m + 1, res}if s[m] > k && s[m-1] < k {return m, res}if s[m] < k {lo = m + 1} else if s[m] > k {hi = m - 1} else {return m, true}}return -1, false}type Int_Map struct {dataMap  map[int]interface{}keyArray []int}func NewIntMap(cap int) *Int_Map {return &Int_Map{dataMap:  make(map[int]interface{}),keyArray: make([]int, 0, cap),}
}func (m *Int_Map) Exists(key int) bool {_, exists := m.dataMap[key]return exists
}func (m *Int_Map) Insert(key int, data interface{}) bool {m.dataMap[key] = dataindex, res := findIndexByBinarySearch(m.keyArray, key)if index == -1 {return false}if res == true { //存在则直接返回return true}if len(m.keyArray) == 0 {m.keyArray = append(m.keyArray, key)return true}//追加末尾if index >= len(m.keyArray) {m.keyArray = append(m.keyArray[0:], []int{key}...)} else if index == 0 { //追加头部m.keyArray = append([]int{key}, m.keyArray[:len(m.keyArray)]...)} else { //插入rear := append([]int{}, m.keyArray[index:]...)m.keyArray = append(m.keyArray[0:index], key)m.keyArray = append(m.keyArray, rear...)}return true
}func (m *Int_Map) Erase(key int) {if !m.Exists(key) {return}index, res := findIndexByBinarySearch(m.keyArray, key)if res == false {return}delete(m.dataMap, key)if index == 0 {m.keyArray = m.keyArray[1:]} else if index == len(m.keyArray) {m.keyArray = m.keyArray[:len(m.keyArray)-2]} else {m.keyArray = append(m.keyArray[:index], m.keyArray[index+1:]...)}
}func (m *Int_Map) Size() int {return len(m.keyArray)
}func (m *Int_Map) GetByOrderIndex(index int) (int, interface{}, bool) {if index < 0 || index >= len(m.keyArray) {return -1, nil, false}key := m.keyArray[index]return key, m.dataMap[key], true
}

测试

package mainimport ("Order_Map""fmt""math/rand""reflect""time")func main() {t := time.Now()r := rand.New(rand.NewSource(time.Now().UnixNano()))testmap := Order_Map.NewIntMap(10000)t1 := t.Second()for i := 0; i < 10000; i++ {testmap.Insert(r.Intn(10000), r.Intn(10000))}t = time.Now()t2 := t.Second()fmt.Println("insert  time  span", t2-t1)testmap.Erase(88)for i := 0; i < testmap.Size(); i++ {k, v, _ := testmap.GetByOrderIndex(i)tmp_v := reflect.ValueOf(v)fmt.Println("k:", k, "---", "value:", tmp_v)}t = time.Now()t3 := t.Second()fmt.Println("range  time  span:", t3-t2)
}

算法 | golang 实现 key有序map相关推荐

  1. golang报错 missing key in map literal

    map[string]interface{}用法见:golang学习笔记 ---解析(map[string]interface{})数据格式 - 清明-心若淡定 - 博客园 解决方法见: Golang ...

  2. 初探Golang(4)-map和流程控制语句

    1.map map 是引用类型的,如果声明没有初始化值,默认是nil.空的切片是可以直接使用的,因为他有对应的底层数组,空的map不能直接使用.需要先make之后才能使用. //1, 声明map 默认 ...

  3. Go语言中的Map和List实现有序Map

    Go语言中的Map和List实现有序Map Map定义: Go 中 Map是一种无序的键值对的集合.Map最重要的一点是通过key来快速检索数据,key类似于索引,指向数据的值.Map是一种集合,所以 ...

  4. golang按key值进行升序排序(ksort),对字符串进行sha1哈希

    在对接PHP语言实现的签名的时候,看见对方用了ksort,由于golang里面对map的遍历是无序的,所以用golang实现了对map按key值进行升序排序: package mainimport ( ...

  5. Golang结构体和map

    Golang 文章目录 Golang 1 struct 2 map 3 struct补充 1 struct 在Golang中没有对象,但是有面向对象的思想,有继承,多态,封装的思想. 但是缺少了cla ...

  6. 【Groovy】map 集合 ( 根据 Key 获取 map 集合中对应的值 | map.Key 方式 | map.‘Key’ 方式 | map[‘Key’] 方式 | 代码示例 )

    文章目录 一.根据 Key 获取 map 集合中对应的值 1.通过 map.Key 方式获取 map 集合中的值 Value 2.通过 map.'Key' 方式获取 map 集合中的值 Value 3 ...

  7. 根据key删除Map集合中的key-value映射

    一:在遍历Map时是不可以删除key-value映射的,如果根据key删除,如下: public static void main(String[] args) {Map<String,Obje ...

  8. 获取用户列表为空_数据结构和算法(Golang实现)(15)常见数据结构-列表

    列表 一.列表 List 我们又经常听到 列表 List 数据结构,其实这只是更宏观的统称,表示存放数据的队列. 列表 List:存放数据,数据按顺序排列,可以依次入队和出队,有序号关系,可以取出某序 ...

  9. Hadoop的Mapreduce中Mapper的key和Map的key的区别

    Hadoop的Mapreduce中Mapper的key和Map的key的区别 问题:我们知道Mapreduce 是以键值对的方式进行输入输出的,分为Mapper <k,v,k,v>和Red ...

  10. vrp 节约算法 c++_数据结构和算法(Golang实现)(8.1)基础知识-前言

    基础知识 学习数据结构和算法.我们要知道一些基础的知识. 一.什么是算法 算法(英文algorithm)这个词在中文里面博大精深,表示算账的方法,也可以表示运筹帷幄的计谋等.在计算机科技里,它表示什么 ...

最新文章

  1. [LeetCode] Add Digits
  2. 三代测序(SMRT Sequencing)
  3. Sql Server 数据分页
  4. asp中如何输入html,ASP.NET中输入文本的HTML解析办法
  5. C++最全输入方式总结(cin、get、getchar、getline)
  6. 前端设置使用rem最经典代码
  7. C++中固定长度短字符串比较是否相同,忽略大小写比对时的小技巧
  8. ros-Qt代码环境的搭建
  9. Netty是如何实现TCP心跳机制与断线重连的
  10. linux安装redis清除错误,关于linux redis安装及安装遇到的问题
  11. 10 款最新的 jQuery 内容滑块插件
  12. swagger 基础入门
  13. 百度知道,每天电影资源轻松引流赚钱小项目!
  14. ESXI安装网卡或HBA卡驱动
  15. 利用Python爬虫爬取淘宝商品做数据挖掘分析实战篇,超详细教程!
  16. 请将磁盘插入“U盘(F)“
  17. laya-oppo 广告问题ad had showd, please reload
  18. 阿里云ACA课程之云上安全防护
  19. 中国跨境电商现状及发展前景
  20. Unity 斜坡滑落

热门文章

  1. mac 不显示 外接屏幕_macbook pro 外接显示器显示不完全
  2. js日期格式化 YYMMDD 转 YY-MM-DD 转 YY年MM月DD日
  3. CAN总线负载率原理及计算
  4. Chrome浏览器启动参数大全(命令行参数)
  5. MATLAB 神经网络函数
  6. AI虚拟偶像正崛起,是否可以取代你的idol?
  7. pcshare个人版
  8. 微软云计算-私有云概述
  9. 服务器lsass状态代码c0000005,Windows服务器上lsass.exe进程CPU使用率异常问题排查方法...
  10. CentOS安装VMwareTools