zoukankan      html  css  js  c++  java
  • Go标准容器之List

    简介
    Go的标准包container中包含了常用的容器类型,包括conatiner/list,container/heap,container/ring。本篇介绍conatiner/list

    conatiner/list实现了一个双向链表。使用起来与其他语言的动态列表非常相似,3秒钟便可入门。

    3秒钟入门

    package main
    
    import (
    "container/list"
    "fmt"
    )
    
    func main() {
    nums := list.New()
    nums.PushBack(1)
    nums.PushBack(2)
    nums.PushBack(3)
    for e := nums.Front(); e != nil; e = e.Next() {
    fmt.Println(e.Value)
    }
    }

    包中有什么
    包里只导出了两个类型和一个函数:

    表示列表的List类型
    表示列表元素的Element类型

    创建List的函数
    container/list––––––––––––––container/list_
    // 表示双向列表
    type List struct{ ... }
    
    // 表示列表中的元素
    type Element struct{ ... }
    
    // 创建List
    func New() *List
    

      


    下面详细讲解该包的用法。

    Element
    先来看看Element类型:

    container/list––––––––––––––container/list_
    type Element struct {
    Value interface{} // 存储在该元素中的值
    }
    

    可以看到值的类型为 interface{},因此Element可以存储任何值。

    创建List
    使用New来创建List,函数原型如下:

    container/list––––––––––––––container/list_
    func New() *List
    

    示例:

    oll := list.New()
    添加元素
    List导出了六个方法用于添加元素:
    
    container/list––––––––––––––container/list_
    // 追加新元素到末尾,返回该元素指针
    func (l *List) PushBack(v interface{}) *Element
    // 追加另一个列表到末尾
    func (l *List) PushBackList(other *List)
    // 添加新元素到开头,返回该元素指针
    func (l *List) PushFront(v interface{}) *Element
    // 添加另一个列表到开头
    func (l *List) PushFrontList(other *List)
    // 在mark后面插入新元素,返回新元素指针
    func (l *List) InsertAfter(v interface{}, mark *Element) *Element
    // 在mark前插入新元素,返回新元素指针
    func (l *List) InsertBefore(v interface{}, mark *Element) *Element
    

    示例:

    // 追加元素到末尾
    coll.PushBack(1)
    coll.PushBack("Gopher")
    
    // 添加元素到开头
    coll.PushFront("Cynhard")
    two := coll.PushFront(2)
    
    // 插入元素到two之前
    before2 := coll.InsertBefore("Before2", two)
    
    // 插入元素到two之后
    after2 := coll.InsertAfter("After2", two)
    
    coll2 := list.New()
    coll2.PushBack(3)
    coll2.PushFront("Tomcat")
    
    // 追加另外一个列表到末尾
    coll.PushBackList(coll2)
    
    // 添加另外一个列表到开头
    coll.PushFrontList(coll2)
    

    应注意到一个列表中的元素的值的类型不必一致。

    移动元素
    List导出了四个方法用于移动元素:

    container/list––––––––––––––container/list_
    // 移动e到mark之后
    func (l *List) MoveAfter(e, mark *Element)
    // 移动e到mark之前
    func (l *List) MoveBefore(e, mark *Element)
    // 移动e到末尾
    func (l *List) MoveToBack(e *Element)
    // 移动e到开头
    func (l *List) MoveToFront(e *Element)
    

    注意e和mark都必须是l的内的元素,否则该函数不执行任何动作。

    示例:

    two := coll.PushFront(2)
    before2 := coll.InsertBefore("Before2", two)
    after2 := coll.InsertAfter("After2", two)
    
    // 将before2移动到two的后面
    coll.MoveAfter(before2, two)
    // 将after2移动到two的前面
    coll.MoveBefore(after2, two)
    // 将before2移动到开头
    coll.MoveToFront(before2)
    // 将after2移动到末尾
    coll.MoveToBack(after2)
    

    访问元素

    List导出了Back()和Front()返回结尾和开头元素:

    container/list––––––––––––––container/list_
    // 返回结尾元素
    func (l *List) Back() *Element
    // 返回开头元素
    func (l *List) Front() *Element
    

    示例:

    fmt.Println(coll.Front().Value) // 打印开头元素的值
    fmt.Println(coll.Back().Value) // 打印结尾元素的值
    

    遍历列表
    Element导出了两个方法Prev()和Next()用以访问前一个或后一个元素:

    container/list––––––––––––––container/list_
    // 返回下一个元素,如果没有下一个元素,返回nil
    func (e *Element) Next() *Element
    // 返回前一个元素,如果没有前一个元素,返回nil
    func (e *Element) Prev() *Element
    

    示例:

    // 顺序遍历
    for e := coll.Front(); e != nil; e = e.Next() {
    fmt.Print(e.Value, " ")
    }
    fmt.Println()
    // 逆序遍历
    for e := coll.Back(); e != nil; e = e.Prev() {
    fmt.Print(e.Value, " ")
    }
    fmt.Println()

    获取列表长度

    container/list––––––––––––––container/list_
    func (l *List) Len() int
    

    示例:

    mt.Println(coll.Len())
    移除元素
    container/list––––––––––––––container/list_
    // 移除e,返回e的值
    func (l *List) Remove(e *Element) interface{}
    // 清空列表
    func (l *List) Init() *List
    

    示例:

    coll := list.New()
    two := coll.PushFront(2)
    coll.Remove(two) // 移除two
    coll.Init() // 清空列表
    

    完整示例

    package main
    
    import (
    "container/list"
    "fmt"
    )
    
    func printList(coll *list.List) {
    for e := coll.Front(); e != nil; e = e.Next() {
    fmt.Print(e.Value, " ")
    }
    fmt.Println()
    }
    
    func printListR(coll *list.List) {
    for e := coll.Back(); e != nil; e = e.Prev() {
    fmt.Print(e.Value, " ")
    }
    fmt.Println()
    }
    
    func main() {
    coll := list.New()
    
    coll.PushBack(1)
    coll.PushBack("Gopher")
    
    coll.PushFront("Cynhard")
    two := coll.PushFront(2)
    
    before2 := coll.InsertBefore("Before2", two)
    after2 := coll.InsertAfter("After2", two)
    
    coll.MoveAfter(before2, two)
    coll.MoveBefore(after2, two)
    coll.MoveToFront(before2)
    coll.MoveToBack(after2)
    
    coll2 := list.New()
    coll2.PushBack(3)
    coll2.PushFront("Tomcat")
    
    coll.PushBackList(coll2)
    coll.PushFrontList(coll2)
    
    printList(coll)
    printListR(coll)
    
    fmt.Println(coll.Front().Value)
    fmt.Println(coll.Back().Value)
    
    fmt.Println(coll.Len())
    
    coll.Remove(two)
    
    printList(coll)
    
    coll.Init()
    printList(coll)
    }
    

      

  • 相关阅读:
    泛型程序设计详解(一)
    面向对象三大特性-----封装、继承、多态
    委托与事件-委托事件案例(三)
    委托与事件-事件详解(二)
    委托与事件-委托详解(一)
    抽象类及接口详解
    基础类型详解下
    C#类型详解
    【JVM】-- JVM内存结构
    【redis】-- redis的持久化(作为数据库)
  • 原文地址:https://www.cnblogs.com/dfsxh/p/10318270.html
Copyright © 2011-2022 走看看