8.27Go之容器之list

8.27Go之容器之list

List的特点

一种非连续的存储容器,由多个节点组成。节点通过一些变量记录彼此之间的关系。

列表的实现方法

  • 单链表

  • 双链表


单链表图示:

8.27Go之容器之list

双链表图示:

8.27Go之容器之list

箭头的区别

双链表想切断联系需要改变指针的指向,并且设置加入的节点的指针指向

单链表只需要设置前一位节点的指针指向和自身节点的指针指向

Go语言中,列表使用 container/list 包来实现,内部的实现原理是双链表

  • 初始化列表

  • 在列表中插入元素

  • 从列表中删除元素

  • 遍历列表


初始化列表

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

通过 container/list 包的 New() 函数初始化 list

package main
?
import (
"container/list"
"fmt"
)
?
func main() {
/*初始化一个链表*/
listPractice := list.New()
?
fmt.Println(listPractice)
}

通过 var 关键字声明初始化 list

package main
?
import (
"fmt"
)
?
func main() {
//另一种声明方式
var listPracticeNo2 list.List
?
fmt.Println(listPracticeNo2)
}

列表中的元素特点:

  • 列表并没有具体元素类型的限制,列表的元素可以是任意类型,

  • 给列表中放入了一个 interface{} 类型的值,取出值后,如果要将 interface{} 转换为其他类型将会发生宕机。

在列表中插入元素

双链表支持从队列前方或后方插入元素,方法是 PushFront 和 PushBack。--->中间插入元素需要改变指向

两个方法都会返回一个 *list.Element 结构,需要删除插入的元素,只能通过 *list.Element 配合 Remove() 方法进行删除,这种方法是双链表特性之一。

list当中插入元素:

package main
?
import (
"container/list"
"fmt"
)
?
func main() {
/*声明一个列表*/
listPractice := list.New()
?
fmt.Println(listPractice)
?
/*在列表后面插入一个值*/
listPractice.PushBack("first")
listPractice.PushBack(66)
?
fmt.Println(listPractice) //这个打印会打印处列表当中的值的地址
}

列表插入函数的返回值会提供一个 *list.Element 结构,这个结构记录着列表元素的值以及与其他节点之间的关系等信息

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

方 法 功 能
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"
"fmt"
)
?
func main() {
/*声明一个列表*/
listPractice := list.New()
?
//尾部添加元素
listPractice.PushBack("back")
//头部添加元素
listPractice.PushFront(66)
?
//因为返回的类型是一个*element句柄,所以保存下来
element := listPractice.PushBack("first")
?
/*使用list包中提供的方法在句柄后添加元素*/
listPractice.InsertAfter("second", element) //形参是添加的节点,节点的前一个句柄
?
listPractice.InsertBefore("noon", element)
?
fmt.Println(listPractice)
?
//使用remove删除节点
listPractice.Remove(element)
}

列表元素操作过程:

操作内容 列表元素
listPractice.PushBack("canon") canon
listPractice.PushFront(67) 67, canon
element := listPractice.PushBack("fist") 67, canon, fist
listPractice.InsertAfter("high", element) 67, canon, fist, high
listPractice.InsertBefore("noon", element) 67, canon, noon, fist, high
listPractice.Remove(element) 67, canon, noon, high

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

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

package main
?
import (
"container/list"
"fmt"
)
?
func main() {
/*声明一个列表*/
listPractice := list.New()
?
//尾部添加
listPractice.PushBack("first")
//头部添加
listPractice.PushFront(77)
?
//循环遍历--->注意格式
for i := listPractice.Front(); i != nil; i = i.Next() {
fmt.Println(i.Value)
}
}

8.27Go之容器之list

上一篇:Ubuntu14.04下wine国际版QQ


下一篇:【vc】1_Windows程序内部运行机制