首页 文章详情

golang实现循环单链代码示例

Go语言精选 | 505 2020-09-14 19:41 0 0 0
UniSMS (合一短信)
最近我从阅读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爱好者值得关注


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter