目录
简介
思路
节点结构体
属性
方法
单链表结构体
属性
方法
Init
New
Clear
Len
Front
Back
insert
InsertAfter
PushBack
PushFront
remove
RemoveAfter
RemoveFront
测试
常见问题
怎么遍历呀?
全部代码
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成是元素加指针。
为了能够兼容所有类型,采用空接口。为了更好的封装,用"私有"的next和insert、remove等,看下方详细解释。
type ListNode struct {
Val interface{}
next *ListNode
lst *SingleList
}
Val采用空接口,接收任意数据类型,可通过类型断言再赋给对应类型。
返回下一个节点,O(1)
func (node *ListNode)Next() *ListNode {
return node.next
}
主要用于遍历,我在其他方法中也有调用。
type SingleList struct {
head *ListNode
len int
}
这里其实可以将head的Val用来存储长度,可以稍微节省一点内存,由于还需要类型断言,比较麻烦,就算了
func (lst *SingleList)Init(){
lst.head = new(ListNode)
lst.head.lst = lst
lst.len = 0
}
创建头结点,长度为0,O(1)
func New() *SingleList {
lst := new(SingleList)
lst.Init()
return lst
}
返回创建的单链表,调用了Init,O(1)
func (lst *SingleList)Clear(){
lst.Init()
}
调用Init,利用Go自己的垃圾回收,O(1)
func (lst *SingleList)Len() int {
return lst.len
}
返回单链表长度,O(1)
func (lst *SingleList)Front() *ListNode {
return lst.head.Next()
}
返回第一个节点,就是头结点的下一个节点,空链表情况下为nil,O(1)
func (lst *SingleList)Back() *ListNode {
if lst.len == 0{
return nil
}
cur := lst.head.Next()
for{
if cur.Next() == nil{
return cur
}
cur = cur.Next()
}
}
返回最后一个节点,空链表的情况下为nil,O(n)
func (lst *SingleList)insert(e, at *ListNode) *ListNode{
lst.len++
e.next = at.next
at.next = e
e.lst = lst
return e
}
返回指向插入的节点e的指针。
仅在此函数进行长度增加,其他插入函数调用此函数,O(1)。
func (lst *SingleList)InsertAfter(val interface{}, mark *ListNode) *ListNode {
if mark == nil{
return nil
}
if mark.lst == lst{
return lst.insert(&ListNode{Val:val},mark)
}
return nil
}
生成值为val的节点,并插入链表节点mark后,返回插入的节点,mark为nil或不属于单链表的情况下,返回nil。调用了insert,O(1)
func (lst *SingleList)PushBack(val interface{}) *ListNode{
end := lst.Back()
if end == nil{
return lst.InsertAfter(val,lst.head)
}else {
return lst.InsertAfter(val,end)
}
}
生成值为val的节点,并插入链表尾节点后,调用Back和InsertAfter。返回指向生成节点的指针,O(n)。
func (lst *SingleList)PushFront(val interface{}) *ListNode {
return lst.InsertAfter(val,lst.head)
}
生成值为val的节点,并插入链表头节点后,调用InsertAfter。返回指向生成节点的指针,O(1)。
func (lst *SingleList)remove(e *ListNode) *ListNode{
nextOne := e.next
if nextOne == nil{
return nil
}
lst.len--
e.next = e.next.next
nextOne.lst = nil
return nextOne
}
删除e的下一个节点,返回删除的节点,仅在此函数进行长度减少,其他删除函数调用此函数。e是尾节点时返回nil,O(1)。
func (lst *SingleList)RemoveAfter(e *ListNode) *ListNode{
if e == nil{
return nil
}
if e.lst == lst{
return lst.remove(e)
}
return nil
}
删除指定节点的后一个节点,返回删除的节点,指定元素为尾节点或nil时,返回nil,O(1)
func (lst *SingleList)RemoveFront() *ListNode {
return lst.remove(lst.head)
}
前删,删除第一个节点,返回删除的节点,可能为nil,O(1)
像下面这样就可以了呦
for e := lst.Front(); e != nil; e = e.Next() {
do something with e.Val
}
具体代码和测试代码在:https://gitee.com/frankyu365/datastructure
Go标准库-container/list
更多Go相关内容:Go-Golang学习总结笔记
有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。如果您感觉有所收获,自愿打赏,可选择支付宝18833895206(小于),您的支持是我不断更新的动力。