Go 的容器数据结构

前言

Java 内置了丰富的容器类,不同容器用于处理各种业务场景。 Go 虽然语言设计上和 Java 有很多相似的地方, 但原生并没有支持太多容器类的数据结构,只有 map 和 slice。标准库的 container package 对容器数据结构做了扩展,支持堆(Heap)、链表(LinkedList) 和循环链表(Circular List)3个容器。

容器

熟悉 C++ 和 Java 对容器应该都有清晰的了解, 它是现代编程实践中不可或缺的一部分,具有多种形式, 一般被描述为具有操作容器内容的方法的对象。Go 提供的基本容器主要有6个:

  • 内置容器:

    • map: 关联容器

    • slice: 动态扩容的顺序容器

  • channels:队列

  • container标准库(pkg/container):

    • list:链表容器
    • ring:循环链表容器
    • heap: 堆容器,提供 heap 的实现

slice 、map 和 channel 是 Go 最常见、也是内置的容器数据结构,其他容器都在标准库的 container 包下。在使用 container 三个容器的时候,不必再费心实现数据结构相关的算法。同时,因为container 提供的容器支持的入参类型都是 interface{}, 所以只要实现了容器的 interface, 就可以处理任何类型的值。

container/list

链表容器 list 的代码是一个双向链表的实现。list 维护两个结构体:Element 和 List:

// 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{
   }
}

// 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.New() 创建一个 list 时,会初始化一个 Element 作为 Root Pointer,它要么指向列表的初始元素,要么为 nil。每一个 Element 除了数据字段Value外,还有 prevnext 分别指向 直接前驱 和 直接后继, 来允许用户在 list 中前后移动元素。

list 容器支持的方法如下:

type Element
    func (e *Element) Next() *Element
    func (e *Element) Prev() *Element
type List
    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 // 在某个元素后插入
    func (l *List) InsertBefore(v interface{
   }, mark *Element) *Element  // 在某个元素前插入
    func (l *List) Len() int // 在链表长度
    func (l *List) MoveAfter(e, mark *Element)  // 把 e 元素移动到 mark 之后
    func (l *List) MoveBefore(e, mark *Element)  // 把 e 元素移动到 mark 之前
    func (l *List) MoveToBack(e *Element) // 把 e 元素移动到队列最后
    func (l *List) MoveToFront(e *Element) // 把 e 元素移动到队列最头部
    func (l *List) PushBack(v interface{
   }) *Element  // 在队列最后插入元素
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值