golang实现循环单链代码示例

共 3119字,需浏览 7分钟

 ·

2020-09-14 19:41

最近我从阅读golang的源码,了解了channel的底层实现,用了一个循环队列,和双端链表。golang的map使用bucket存储key和value使用了链表,发现golang的底层实现还是比较有意思的。所以我学着用golang实现一个循环单链的代码示例,下面我们来看一下循环单链的实现,循环单链实现了,插入数据,删除某个节点数据,翻转数据,获取长度等功能,代码大家就直接对着源码看看吧,我就没有对代码进行分段讲解了,最后面我们贴一下这个代码运行的结果。
package main
import "fmt"
//定义节点的数据结构type Node struct { data interface{} next *Node}
//单链的数据结构type OneCycleList struct { size int head *Node}
//获取链表的头部func (o *OneCycleList) GetHead() *Node { return o.head}
//获取长度func (o *OneCycleList) GetSize() int { return o.size}
//获取节点装的数据func (o *Node) GetData() interface{} { return o.data}
//获取下一个节点的地址func (o *Node) GetNext() *Node { return o.next}
//添加链表数据func (o *OneCycleList) Append(data interface{}) bool { node := Node{} //添加data数据 node.data = data if o.GetSize() == 0 { o.head = &node } else { item := o.GetHead() //找到链表尾部,当当前的这个链表的头部 == next下一个链表地址的时候 //循环链表的最后一个next指向第一个的head 是相等的 for ; item.next != o.GetHead(); item = item.next { } //这里是把数据挂到链表的next item.next = &node } node.next = o.head o.size++ return true}
//基于某个node进行,插入节点数据func (o *OneCycleList) InsertNext(elment *Node, data interface{}) bool { if elment == nil { return false } //处理新节点数据装载到链表中 node := Node{} node.data = data node.next = elment.next elment.next = &node o.size++ return true}
//删除某个节点的数据,并返回该数据func (o *OneCycleList) Remove(elment *Node) interface{} { if elment == nil { return nil } item := o.GetHead() //找到elment的前一个节点 for ; item.next != elment; item = item.next { } //将elment的前面一个节点的next指向当前elment的next,这里就删除了当前的节点elment了 item.next = elment.next o.size-- return elment.GetData()}
//调整所有的节点进行转向func Reverse(head *Node, o *OneCycleList) *OneCycleList { if head.next == o.head { o.head = head return o } p := Reverse(head.next, o) head.next.next = head head.next = p.head return p}
func main() { a := OneCycleList{} //处理好初始化 a.Append(3) a.Append(4) a.Append(8) //基于3后面的节点追加数据 9 a.InsertNext(a.head, 9) temp := a.head fmt.Println("下面是循环打印-------------------") //循环打印链表数据 for { if temp == nil { break } fmt.Print(temp.data, "\n") if temp.next == a.head { break } temp = temp.next } //单向循环链表翻转 b := Reverse(a.head, &a) fmt.Println("翻转之后打印结果-------------------") temp2 := b.head for { if temp2 == nil { break } fmt.Print(temp2.data, "\n") if temp2.next == b.head { break } temp2 = temp2.next } fmt.Println("下面删除一个节点当前节点返回值-------------------") //下面删除一个节点 fmt.Println(b.Remove(b.head.next)) fmt.Println("下面删除一个节点后打印数据-------------------") temp3 := b.head for { if temp3 == nil { break } fmt.Print(temp3.data, "\n") if temp3.next == b.head { break } temp3 = temp3.next }}
下面是代码运行的结果:
下面是循环打印-------------------3948翻转之后打印结果-------------------8493下面删除一个节点当前节点返回值-------------------4下面删除一个节点后打印数据-------------------893
好了,这次我简单讲述循环单链,后面我golang源码研究,根据重点再把循环队列和双端链表实现分享给大家。




推荐阅读



学习交流 Go 语言,扫码回复「进群」即可


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注


浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报