前言
- 最近在学算法,栈的部分涉及到了list包的使用,于是我就打算整理一下它的基本用法。
- 本篇文章只讲到主要用法,并没有讲完所有用法。
(这是List的全部用法。)
1.概述
- 在 Go 语言中,
container/list
包提供了一个实现双向链表的数据结构。这个包中的链表可以高效地在头部、尾部或者中间插入和删除元素,并且支持遍历操作。
2.主要数据结构
List
:这是整个链表的结构体。它包含了链表的头节点和尾节点的指针,以及链表的长度等信息。通过list.New()
函数可以创建一个新的List
实例。Element
:它代表链表中的一个元素。每个元素包含一个指向前后相邻元素的指针(prev
和next
),以及一个用于存储元素值的接口类型的字段(Value
)。接口类型使得Element
可以存储任意类型的值。
3.常用操作方法
- 创建链表
New
函数:- 语法:
func New() *List
。 - 示例:以下所有函数及方法的示例都在基本讲解之后。
- 解释:这是创建一个新的空链表的方法。它返回一个指向
List
结构体的指针,通过这个指针可以对链表进行各种操作。
- 语法:
- 插入元素
PushFront
方法:- 语法:
func (l *List) PushFront(v interface{}) *Element
。 - 解释:将一个元素插入到链表的头部。它接受一个
interface{}
类型的参数(可以是任何类型的值),并返回一个指向新插入元素的*Element
指针。
- 语法:
PushBack
方法:- 语法:
func (l *List) PushBack(v interface{}) *Element
。 - 解释:将一个元素插入到链表的尾部,同样接受任何类型的值作为参数,并返回指向新插入元素的指针。
- 语法:
InsertAfter
方法:- 语法:
func (l *List) InsertAfter(v interface{}, mark *Element) *Element
。 - 解释:在指定的
mark
元素之后插入一个新元素v
。它需要两个参数,一个是要插入的元素值(v
),另一个是已经存在于链表中的*Element
指针(mark
),用于指定插入位置,最后返回指向新插入元素的指针。
- 语法:
InsertBefore
方法:- 语法:
func (l *List) InsertBefore(v interface{}, mark *Element) *Element
。 - 解释:在指定的mark元素之前插入一个新元素v,参数和返回值的类型与
InsertAfter
类似。
- 语法:
//New函数
l := list.New();
//PushFront方法
l := list.New(); element := l.PushFront(10);
//PushBack方法
l := list.New(); element := l.PushBack(20);
//InsertAfter方法
l := list.New();
element1 := l.PushBack(30);
element2 := l.InsertAfter(40, element1);
//InsertBefore方法
l := list.New();
element1 := l.PushBack(50);
element2 := l.InsertBefore(60, element1);
- 遍历元素
-
ForEach
方法:- 语法:
func (l *List) ForEach(f func(interface{}))
。 - 示例:示例在后面。
- 语法:
-
通过迭代器遍历:
- 可以使用
Front
和Next
方法进行迭代。Front
方法返回链表的第一个元素的*Element
指针,Next
方法用于获取当前元素的下一个元素的指针。 - 示例:
l := list.New(); l.PushBack(4); l.PushBack(5); l.PushBack(6);for e := l.Front(); e!= nil; e = e.Next() { fmt.Println(e.Value) }
。 - 解释:首先通过
l.Front()
获取链表头部元素的指针,然后在循环中通过e.Next()
不断获取下一个元素的指针,直到e
为nil
(表示到达链表尾部),在循环体中可以通过e.Value
访问每个元素的值并进行相应操作。 Front
方法- 语法:
func (l *List) Front() *Element
。 - 功能:这个方法用于获取链表的第一个元素(头部元素)的指针。它是一个
*Element
类型的指针,如果链表为空,则返回nil
。
- 语法:
Next
方法- 语法:
func (e *Element) Next() *Element
。 - 功能:
Next
方法是定义在Element
结构体上的方法。它用于获取当前元素的下一个元素的指针。如果当前元素是链表中的最后一个元素,那么Next
方法返回nil
。 - 示例:
- 语法:
- 可以使用
-
//ForEach方法
l := list.New();
l.PushBack(1);
l.PushBack(2);
l.PushBack(3);
l.ForEach(func(v interface{}) { fmt.Println(v) });
//Front方法
func main() {
myList := list.New()
myList.PushBack(10)
myList.PushBack(20)
firstElement := myList.Front()
if firstElement!= nil {
fmt.Println(firstElement.Value)
}
}
//Next方法
func main() {
myList := list.New()
element1 := myList.PushBack(30)
element2 := myList.PushBack(40)
currentElement := element1
nextElement := currentElement.Next()
if nextElement == element2 {
fmt.Println("Next element is correct")
}
}
- 删除元素
Remove
方法:- 语法:
func (l *List) Remove(e *Element) interface{}
。 - 解释:从链表中删除指定的
*Element
。它接受一个指向要删除元素的指针e
,并返回被删除元素的值(interface{}
类型)。这在需要获取被删除元素的值或者清理链表中的特定元素时非常有用。 - 示例:
- 语法:
l := list.New();
element := l.PushBack(7);
l.Remove(element);
结语
- 其实
list
包里面还封装了很多方法,大家有兴趣可以去看看源码。 - 这篇文章到这里就结束了,希望能够帮到你。