加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

实现有序map之go

发布时间:2020-12-16 09:44:17 所属栏目:大数据 来源:网络整理
导读:Go Map介绍 Go 中 Map是一种无序的键值对的集合。Map最重要的一点是通过key来快速检索数据,key类似于索引,指向数据的值。Map是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map是无序的,我们无法决定它的返回顺序,这是因为Map是使用链式has

Go Map介绍

Go 中 Map是一种无序的键值对的集合。Map最重要的一点是通过key来快速检索数据,key类似于索引,指向数据的值。Map是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map是无序的,我们无法决定它的返回顺序,这是因为Map是使用链式hash表来实现的。

c++中的实现

在C++ STL 中map 采用红黑树实现,可以实现有序的Map.

Go 中实现

实现原理

这个实现方法的主要的方法是用空间换取时间。通过list 和 map 两种数据结构,保存相同的一份数据。list 用来做顺序遍历,map 用来做查找,删除操作

实现代码

package main

import (
    "container/list"
    "fmt"
)

type Keyer interface {
    GetKey() string
}

type MapList struct {
    dataMap  map[string]*list.Element
    dataList *list.List
}

func NewMapList() *MapList {
    return &MapList{
        dataMap:  make(map[string]*list.Element),dataList: list.New(),}
}

func (mapList *MapList) Exists(data Keyer) bool {
    _,exists := mapList.dataMap[string(data.GetKey())]
    return exists
}

func (mapList *MapList) Push(data Keyer) bool {
    if mapList.Exists(data) {
        return false
    }
    elem := mapList.dataList.PushBack(data)
    mapList.dataMap[data.GetKey()] = elem
    return true
}

func (mapList *MapList) Remove(data Keyer) {
    if !mapList.Exists(data) {
        return
    }
    mapList.dataList.Remove(mapList.dataMap[data.GetKey()])
    delete(mapList.dataMap,data.GetKey())
}

func (mapList *MapList) Size() int {
    return mapList.dataList.Len()
}

func (mapList *MapList) Walk(cb func(data Keyer)) {
    for elem := mapList.dataList.Front(); elem != nil; elem = elem.Next() {
        cb(elem.Value.(Keyer))
    }
}

type Elements struct {
    value string
}

func (e Elements) GetKey() string {
    return e.value
}

func main() {
    fmt.Println("Starting test...")
    ml := NewMapList()
    var a,b,c Keyer
    a = &Elements{"Alice"}
    b = &Elements{"Bob"}
    c = &Elements{"Conrad"}
    ml.Push(a)
    ml.Push(b)
    ml.Push(c)
    cb := func(data Keyer) {
        fmt.Println(ml.dataMap[data.GetKey()].Value.(*Elements).value)
    }
    fmt.Println("Print elements in the order of pushing:")
    ml.Walk(cb)
    fmt.Printf("Size of MapList: %d n",ml.Size())
    ml.Remove(b)
    fmt.Println("After removing b:")
    ml.Walk(cb)
    fmt.Printf("Size of MapList: %d n",ml.Size())
}

优点

红黑树的插入、删除、查找的复杂度都是 O(logn),而这个实现插入查找删除的复杂度都是 O(1),可以说是一种非常好的数据结构。

缺点

使用了两个数据结构,空间占用稍微大了一点。但是和树的实现比,这个占用也不算非常大

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读