golang中container/list包源码分析

golang源码包中container/list实际上是一个双向链表

提供链表的一些基本操作,下面就结合定义和接口进行下说明

1. 定义

复制代码
// Element is an element of a linked list.
type Element struct {
    // Next and previous pointers in the doubly-linked list of elements.
    // To simplify the implementation, internally a list l is implemented
    // as a ring, such that &l.root is both the next element of the last
    // list element (l.Back()) and the previous element of the first list
    // element (l.Front()).
    next, prev *Element

    // The list to which this element belongs.
    list *List

    // The value stored with this element.
    Value interface{}
}
复制代码

Element是数据节点, 提供Next()/Prev()这类常规操作

// List represents a doubly linked list.
// The zero value for List is an empty list ready to use.
type List struct {
    root Element // sentinel list element, only &root, root.prev, and root.next are used
    len  int     // current list length excluding (this) sentinel element
}

List双向链表定义

 

2. 接口说明

复制代码
func New() *List                                                    //创建一个双向链表
func (l *List) Back() *Element                                      //返回双向链表上一个元素
func (l *List) Front() *Element                                     //返回双向链表下一个元素
func (l *List) Init() *List                                         //初始化链表
func (l *List) InsertAfter(v interface{}, mark *Element) *Element   //在指定节点后插入,成功返回插入节点的指针,失败返回nil, 时间复杂度O(1)
func (l *List) InsertBefore(v interface{}, mark *Element) *Element  //在指定节点之前插入, 成功返回插入节点的指针,失败返回nil, 时间复杂度O(1)
func (l *List) Len() int                                            //返回链表长度,时间复杂度O(1)
func (l *List) MoveAfter(e, mark *Element)                          //移动节点e到mark节点之后,时间复杂度O(1), 处理方式:先删除然后再插入
func (l *List) MoveBefore(e, mark *Element)                         //移动节点e到mark节点之前,时间复杂度O(1), 处理方式:先删除然后再插入
func (l *List) MoveToBack(e *Element)                               //移动节点e到链表的尾部
func (l *List) MoveToFront(e *Element)                              //移动节点e到链表的头部
func (l *List) PushBack(v interface{}) *Element                     //在链表尾部追加值为v的新节点
func (l *List) PushBackList(other *List)                            //把链表other所有节点追加到当前链表的尾部
func (l *List) PushFront(v interface{}) *Element                    //在链表的头部插入新节点
func (l *List) PushFrontList(other *List)                           //把链表other所有节点追加到当前链表头部
func (l *List) Remove(e *Element) interface{}                       //删除指定节点
    
复制代码

 

3. 实例

复制代码
// Create a new list and put some numbers in it.
l := list.New()
e4 := l.PushBack(4)
e1 := l.PushFront(1)
l.InsertBefore(3, e4)
l.InsertAfter(2, e1)

// Iterate through list and print its contents.
for e := l.Front(); e != nil; e = e.Next() {
    fmt.Println(e.Value)
}

Output:
1
2
3
4
复制代码

 

posted @   davygeek  阅读(1685)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示