go基础之List、Queue、Deque、Stack

一、List定义

概述
1、list是一种非连续存储的容器,由多个节点组成,节点通过一些变量记录彼此之间的关系。list有多种实现方法,如单向链表、双向链表等。
2、Go语言中list的实现原理是双向链表。list能高效地进行任意位置的元素插入和删除操作

由于底层是双向链表,故完全可以用于模拟队列,双端队列,栈等结构(Java中的Queue、Deque、Stack底层就是LinkedList双向链表呀)

go中的list

  • Golan的标准库提供了高级的数据结构List。具体在包 container/list。
  • container/list包里主要有两个数据结构类型:“ Element”、“List”;
  • Element类型代表双向链表中的一个元素,相当于C++里面的" iterator";
  • List代表一个双向链表。List零值为一个空的、可用的链表。
  • Element有Prev和Next方法用于得到前一个或者下一个 Element,Element可以直接调用 Value属性;

二、list的使用

1、 通过container/list包的New方法声明list

  • 变量名 := list.New()

2、通过var声明list

  • var 变量名 list.List
  • list与切片和map不同,没有具体元素类型的限制。list中的元素可以是任意类型。
  • 在CPP里面,list的成员必须是同一个数据类型,但是Go语言中却允许list中插入任意类型的成员。
  • 建议使用New()实现声明list

三 具体使用方法

在Go语言中,列表使用 container/list 包来实现,内部的实现原理是双链表,列表能够高效地进行任意位置的元素插入和删除操作。

初始化列表

list 的初始化有两种方法:分别是使用 New() 函数和 var 关键字声明,两种方法的初始化效果都是一致的。

  1. 通过 container/list 包的 New() 函数初始化 list
变量名 := list.New()
  1. 通过 var 关键字声明初始化 list
var 变量名 list.List

列表与切片以及 map 不同的是,列表并没有具体元素类型的限制,因此,列表的元素可以是任意类型,这既带来了便利,也引来一些问题,例如给列表中放入了一个 interface{} 类型的值,取出值后,如果要将 interface{} 转换为其他类型需要使用类型断言

在列表中插入元素

双链表支持从队列前方或后方插入元素,分别对应的方法是 PushFront 和 PushBack。

提示

这两个方法都会返回一个 *list.Element 结构,如果在以后的使用中需要删除插入的元素,则只能通过 *list.Element 配合 Remove() 方法进行删除,这种方法可以让删除更加效率化,同时也是双链表特性之一。

下面代码展示如何给 list 添加元素:

l := list.New()

l.PushBack("first")
l.PushFront(67)

代码说明如下:

  • 第 1 行,创建一个列表实例。
  • 第 3 行,将 fist 字符串插入到列表的尾部,此时列表是空的,插入后只有一个元素。
  • 第 4 行,将数值 67 放入列表,此时,列表中已经存在 first 元素,67 这个元素将被放在 first 的前面。

列表插入元素的方法如下表所示。

方 法功 能
InsertAfter(v interface {}, mark * Element) * Element在 mark 点之后插入元素,mark 点由其他插入函数提供
InsertBefore(v interface {}, mark * Element) *Element在 mark 点之前插入元素,mark 点由其他插入函数提供
PushBackList(other *List)添加 other 列表元素到尾部
PushFrontList(other *List)添加 other 列表元素到头部

从列表中删除元素

列表插入函数的返回值会提供一个 *list.Element 结构,这个结构记录着列表元素的值以及与其他节点之间的关系等信息,从列表中删除元素时,需要用到这个结构进行快速删除。

列表操作元素:

package main

import "container/list"

func main() {
    l := list.New()

    // 尾部添加
    l.PushBack("canon")

    // 头部添加
    l.PushFront(67)

    // 尾部添加后保存元素句柄
    element := l.PushBack("first")

    // 在first之后添加high
    l.InsertAfter("high", element)

    // 在first之前添加noon
    l.InsertBefore("noon", element)

    // 使用
    l.Remove(element)
}

代码说明如下:
第 6 行,创建列表实例。
第 9 行,将字符串 canon 插入到列表的尾部。
第 12 行,将数值 67 添加到列表的头部。
第 15 行,将字符串 first 插入到列表的尾部,并将这个元素的内部结构保存到 element 变量中。
第 18 行,使用 element 变量,在 element 的位置后面插入 high 字符串。
第 21 行,使用 element 变量,在 element 的位置前面插入 noon 字符串。
第 24 行,移除 element 变量对应的元素。

下表中展示了每次操作后列表的实际元素情况。

操作内容列表元素
l.PushBack(“canon”)canon
l.PushFront(67)67, canon
element := l.PushBack(“first”)67, canon, first
l.InsertAfter(“high”, element)67, canon, first, high
l.InsertBefore(“noon”, element)67, canon, noon, first, high
l.Remove(element)67, canon, noon, high

遍历列表——访问列表的每一个元素

遍历双链表需要配合 Front() 函数获取头元素,遍历时只要元素不为空就可以继续进行,每一次遍历都会调用元素的 Next() 函数,代码如下所示。

l := list.New()

// 尾部添加
l.PushBack("canon")

// 头部添加
l.PushFront(67)

for i := l.Front(); i != nil; i = i.Next() {
    fmt.Println(i.Value)
}

代码输出如下:

67
canon

代码说明如下:

  • 第 1 行,创建一个列表实例。
  • 第 4 行,将 canon 放入列表尾部。
  • 第 7 行,在队列头部放入 67。
  • 第 9 行,使用 for 语句进行遍历,其中 i:=l.Front() 表示初始赋值,只会在一开始执行一次,每次循环会进行一次 i != nil 语句判断,如果返回 false,表示退出循环,反之则会执行 i = i.Next()。
  • 第 10 行,使用遍历返回的 *list.Element 的 Value 成员取得放入列表时的原值。

本博客摘自多个博客内容,主要给自己做笔记之用
更详细的内容可看:https://blog.csdn.net/u011304970/article/details/72782412

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值