首页 > 其他分享 >Go标准库:container/list

Go标准库:container/list

时间:2024-07-03 17:54:48浏览次数:15  
标签:元素 container int cache list 链表 Go

Go标准库:container/list

原创 孟斯特 孟斯特 2024-07-03 16:03 北京 听全文

在Go语言的标准库中,container/list包提供了一个双向链表的实现,这对于需要频繁插入和删除操作的场景非常有用。双向链表是一种线性数据结构,它由一系列节点组成,每个节点包含数据和两个指针,分别指向前一个节点和后一个节点。下面我们将详细介绍如何使用container/list包,以及它的内部实现和常见操作。

导入包

首先,我们需要导入container/list包:

import "container/list"

初始化链表

我们可以通过调用list.New()函数或者直接声明一个list.List类型的变量来初始化一个链表:

// 方法一:使用list.New()函数
l := list.New()

// 方法二:直接声明一个list.List变量
var l list.List

基本操作

添加元素

container/list包提供了多种方法来向链表中添加元素:

  • • PushFront(v interface{}) *Element:在链表的头部插入一个元素,返回该元素的指针。

  • • PushBack(v interface{}) *Element:在链表的尾部插入一个元素,返回该元素的指针。

  • • InsertBefore(v interface{}, mark *Element) *Element:在指定元素之前插入一个新元素。

  • • InsertAfter(v interface{}, mark *Element) *Element:在指定元素之后插入一个新元素。

l := list.New()
l.PushBack("Go")
l.PushFront(42)
e := l.PushBack(3.14)
l.InsertBefore("before", e)
l.InsertAfter("after", e)

删除元素

可以使用Remove方法删除链表中的元素,Remove方法接受一个指向链表元素的指针,删除该元素并返回其值:

l := list.New()
e := l.PushBack("to be removed")
l.Remove(e)

遍历链表

可以使用Front()Back()方法获取链表的第一个和最后一个元素,然后通过元素的Next()Prev()方法进行遍历:

// 从前向后遍历
for e := l.Front(); e != nil; e = e.Next() {
    fmt.Println(e.Value)
}

// 从后向前遍历
for e := l.Back(); e != nil; e = e.Prev() {
    fmt.Println(e.Value)
}

链表的特性

  • • 双向链表:每个节点有两个指针,分别指向前一个节点和后一个节点。

  • • O(1)时间复杂度的插入和删除:链表的插入和删除操作都只需要调整指针,因此效率很高。

  • • 遍历效率较低:由于链表节点不连续存储,无法利用CPU缓存,遍历效率相对于数组较低。

常见应用场景

  1. 1. 需要频繁插入和删除操作的场景:由于链表插入和删除操作的时间复杂度为O(1),在需要频繁进行这些操作时,链表表现优异。

  2. 2. 实现LRU缓存:链表和哈希表的结合可以高效实现LRU(最近最少使用)缓存。

  3. 3. 队列和双端队列:链表可以方便地实现FIFO队列和双端队列。

示例:实现一个简单的LRU缓存

下面是一个使用container/listmap实现的简单LRU缓存的例子:

package main

import(
"container/list"
"fmt"
)

typeLRUCachestruct{
    capacity int
    list     *list.List
    cache    map[int]*list.Element
}

type entry struct{
    key   int
    value int
}

func NewLRUCache(capacity int)*LRUCache{
return&LRUCache{
        capacity: capacity,
        list:     list.New(),
        cache:make(map[int]*list.Element),
}
}

func (c *LRUCache)Get(key int)(int,bool){
if e, ok = c.cache[key]; ok {
        c.list.MoveToFront(e)
return e.Value.(*entry).value,true
}
return-1,false
}

func (c *LRUCache)Put(key, value int){
if e, ok = c.cache[key]; ok {
        c.list.MoveToFront(e)
        e.Value.(*entry).value = value
}else{
if c.list.Len()== c.capacity {
            back := c.list.Back()
            c.list.Remove(back)
delete(c.cache, back.Value.(*entry).key)
}
        e :=&entry{key, value}
        listElement := c.list.PushFront(e)
        c.cache[key]= listElement
}
}

func main(){
    cache :=NewLRUCache(2)
    cache.Put(1,1)
    cache.Put(2,2)
    fmt.Println(cache.Get(1))// 返回1
    cache.Put(3,3)
    fmt.Println(cache.Get(2))// 返回-1 (未找到)
    cache.Put(4,4)
    fmt.Println(cache.Get(1))// 返回-1 (未找到)
    fmt.Println(cache.Get(3))// 返回3
    fmt.Println(cache.Get(4))// 返回4
}
孟斯特 个人分享 258篇原创内容 公众号

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)[1]进行许可,使用时请注明出处。
Author: mengbin[2]
blog: mengbin[3]
Github: mengbin92[4]
cnblogs: 恋水无意[5]
腾讯云开发者社区:孟斯特[6]


引用链接

[1] 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0): https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh
[2] mengbin: [email protected]
[3] mengbin: https://mengbin.top
[4] mengbin92: https://mengbin92.github.io/
[5] 恋水无意: https://www.cnblogs.com/lianshuiwuyi/
[6] 孟斯特: https://cloud.tencent.com/developer/user/6649301

 

Golang132 Golang · 目录 上一篇PKCS#12 个人观点,仅供参考 阅读 18 ​   喜欢此内容的人还喜欢   单元测试     我关注的号 孟斯特   不看的原因   Golang 依赖注入设计哲学|12.6k star 的 DI 库 wire     白泽talk   不看的原因   Golang面试题:协程Goroutine     我看过的号 Coding Big Tree   不看的原因 写留言     孟斯特            

人划线

 

标签:元素,container,int,cache,list,链表,Go
From: https://www.cnblogs.com/cheyunhua/p/18282289

相关文章

  • go当中的线程存储与使用
    1、settls从引导代码中可以看到,在执行settls前将m.tls放入了DI。go/src/runtime/asm_amd64.s:159TEXTruntime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0....LEAQruntime·m0+m_tls(SB),DICALLruntime·settls(SB)....tls定义是无符号整形指针ty......
  • unity 从list中获取最近的坐标 / 获取最接近的角度(数值)
    ///<summary>///从列表points中获取距离targetPoint最近的坐标///</summary>///<paramname="points"></param>///<paramname="targetPoint"></param>///<returns><......
  • go基本操作
    1.gowsl环境搭建注意事项:ubuntu必须安装在系统盘(C盘)VSode插件下载:koroFileHeader自动添加注释:VScode自动添加注释_vscode自动注释-CSDN博客go中文下载地址:Go下载-Go语言中文网-Golang中文社区golang开发环境下载:Allreleases-TheGoProgrammingLanguagego中文......
  • Golang面试:泛型
    Go语言在1.18版本中引入了泛型(Generics),这是Go语言发展中的一个重要里程碑。泛型允许你编写更通用和可复用的代码,而无需牺牲类型安全性。以下是对Go中泛型的详细介绍,包括其语法、使用场景和示例代码。1.泛型的基本概念泛型允许你定义可以处理多种数据类型的函数和数据结构,而无需......
  • Golang开发:构建支持并发的网络爬虫
    Golang开发:构建支持并发的网络爬虫随着互联网的快速发展,获取网络数据成为了许多应用场景中的关键需求。网络爬虫作为一种自动化获取网络数据的工具,也因此迅速崛起。而为了应对日益庞大的网络数据,开发支持并发的爬虫成为了必要的选择。本文将介绍如何使用Golang编写一个支持......
  • lombard waitlist
    fromcurl_cffiimportrequestsfrompprintimportpprintimporttimedefsend_mail(mail):pprint(mail)headers={'accept':'*/*','accept-language':'zh-CN,zh;q=0.9','cache-c......
  • Django 自定义用户表
    当默认的用户表中字段不足以满足我们的业务需求时,可以自己继承和重写用户表,增加想要的字段。1.自定义用户表模型fromdjango.dbimportmodelsfromdjango.contrib.auth.modelsimportAbstractUser#重新定义用户表classUserProfile(AbstractUser):avatar=model......
  • django使用jinja2模板
    1.使用Django默认模板TEMPLATES=[{'BACKEND':'django.template.backends.django.DjangoTemplates','DIRS':[BASE_DIR/'templates'],#使用路径表达式'APP_DIRS':True,'OPTIO......
  • 差异基因富集分析(R语言——GO&KEGG&GSEA)
    接着上次的内容,上篇内容给大家分享了基因表达量怎么做分组差异分析,从而获得差异基因集,想了解的可以去看一下,这篇主要给大家分享一下得到显著差异基因集后怎么做一下通路富集。1.准备差异基因集我就直接把上次分享的拿到这边了。我们一般都把差异基因分为上调基因和下调基因分......
  • 前端视角下的Go语法学习:demo-crud 实现增删改查
    今日话题基于go+gin实现增删改查,仅仅只是提供接口不涉及数据库增删改查作者:云层上的光时间:2024年6月22日10时15分14秒主线任务一、项目创建1、创建demo-crud文件夹2、编辑器打开demo-crud项目,提示设置gosdk,这里我设置了1.22.43、声明go.mod文件go......