Go 标准库-双向链表 (container/list) 源码解析

本文详细介绍了Go语言中的container/list包,该包用于实现双向链表。链表是一种非连续存储的数据结构,container/list提供了插入、删除和遍历等操作。文章通过源码解析展示了如何使用Element结构体构建链表节点,以及List结构体如何作为链表的头部和尾部标识。此外,还介绍了如何初始化、插入元素、删除元素以及遍历链表的操作。

container/list双向链表解析

概述

container/list包实现了基本的双向链表功能,包括元素的插入、删除、移动功能。

链表

链表是一种非连续存储的容器,由多个节点组成,节点通过一些变量记录彼此之间的关系。列表有多种实现方法,如单链表、双链表等

列表的原理可以这样理解:假设 A、B、C 三个人都有电话号码,如果 A 把号码告诉给 B,B 把号码告诉给 C,这个过程就建立了一个单链表结构,如下图所示。
请添加图片描述
如果在这个基础上,再从 C 开始将自己的号码给自己知道号码的人,这样就形成了双链表结构,如下图所示
请添加图片描述
那么如果需要获得所有人的号码,只需要从 A 或者 C 开始,要求他们将自己的号码发出来,然后再通知下一个人如此循环。这个过程就是列表遍历

如果 B 换号码了,他需要通知 A 和 C,将自己的号码移除。这个过程就是列表元素的删除操作,如下图所示
请添加图片描述
在 Go 语言中,链表使用 container/list 包来实现,内部的实现原理是双链表。列表能够高效地进行任意位置的元素插入和删除操作

源码解析

实现原理

// Element 元素结构体
type Element struct {
   
   
  // 上一个和下一个元素节点的指针
  next, prev *Element
  // 这个元素所属的列表
  list       *List
  // 该节点存储的数据
  Value      interface{
   
   }
}

请添加图片描述
根据节点的定义可以得出以上示意图,各个节点之间有两个引用分别指向上一个节点和下一个节点,由此可看到该链表可以在左边第一个元素或向右进行遍历, 也可以在右边第一个元素向左开始遍历

这时便有一个问题,怎么记录该链表的的头节点和尾节点?这就需要用到我们上面提过的list了

先来看一下List的定义:

type List struct {
   
   
  // 哨兵元素,仅使用&root、root.prev和root.next
  root Element
  // 列表长度,不包括哨兵(root)元素
  len  int
}
<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值