继上一篇单向链表,单线链表可以进一步扩展为环,如下图所示:
特点:
1,第一个节点称为头部节点,最后一个节点称为尾部节点
2,每个节点都单方面的指向下一个节点
3,尾部节点下一个节点指向头部节点
题目:
17世纪的法国数学家加斯帕讲& # 63930;这样一个故事:15个教徒和15个非教徒,在深海& # 64069;上遇险,必须将一半的人投入海& # 64069;中,其余的人才能幸免于难,于是想& # 63930;一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海& # 64069;,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海& # 64069;的都是非教徒。
这就是典型的约瑟夫环问题,可以用单向链表环解决,具体代码如下:
主要包 进口“fmt” LinkNode struct类型{ 数据接口{} 下一个* LinkNode } SingleLink struct类型{ 头* LinkNode 尾* LinkNode 大小int }//初始化链表 func InitSingleLink () (* SingleLink) { 返回,SingleLink { 头:nil, 尾巴:nil, 大小:0, } }//获取头部节点 func (sl * SingleLink) GetHead () * LinkNode { 返回sl.head }//获取尾部节点 func (sl * SingleLink) GetTail () * LinkNode { 返回sl.tail }//打印链表 func (sl * SingleLink) Print () { fmt。Println (“SingleLink大小:sl.Length ()) 如果sl.size==0 { 返回 } ptr:=sl.GetHead () headNode:=sl.GetHead () ptr !=nil { ptr.Data fmt.Println("数据:") ptr=ptr.Next 如果ptr。下一个==headNode { ptr.Data fmt.Println("数据:") 打破 } } }//链表长度 int func (sl * SingleLink)长度(){ 返回sl.size }//插入数据(头插) func (sl * SingleLink) InsertByHead(节点* LinkNode) { 如果节点==nil { 返回 }//判断是否第一个节点 如果sl.Length ()==0 { sl.head=节点 sl.tail=节点 节点。下一个=nil 其他}{ oldHeadNode:=sl.GetHead () sl.head=节点 sl.tail。下一个=节点 sl.head。下一个=oldHeadNode } sl.size + + }//插入数据(尾插) func (sl * SingleLink) InsertByTail(节点* LinkNode) { 如果节点==nil { 返回 }//插入第一个节点 如果sl.size==0 { sl.head=节点 sl.tail=节点 节点。下一个=nil 其他}{ sl.tail。下一个=节点 节点。下一个=sl.head sl.tail=节点 } sl.size + + }//插入数据(下)标位置 func (sl * SingleLink) InsertByIndex(指数int,节点* LinkNode) { 如果节点==nil { 返回 }//往头部插入 如果指数==0 { sl.InsertByHead(节点) 其他}{ 如果指数比;sl.Length () { 返回 其他}如果指数==sl.Length () {//往尾部添加节点 sl.InsertByTail(节点) 其他}{ preNode:=sl.Search(索引1)//下标为指数的上一个节点 currentNode:=sl.Search(指数)//下标为索引的节点 preNode。下一个=节点 节点。下一个=currentNode sl.size + + } } }//删除数据(下)标位置 func (sl * SingleLink) DeleteByIndex(指数int) { 如果sl.Length()==0 | |指数比;sl.Length () { 返回 }//删除第一个节点 如果指数==0 { sl.head=sl.head.Next sl.tail。下一个=sl.head 其他}{ preNode:=sl.Search(索引1) 如果指数!=sl.Length (1) { nextNode:=sl.Search(指数). next preNode。下一个=nextNode 其他}{ sl.tail=preNode preNode。下一个=sl.head } } sl.size—— }//查询数据 func (sl * SingleLink)搜索(指数int)(节点* LinkNode) { 如果sl.Length()==0 | |指数比;sl.Length () { 返回nil }//是否头部节点 如果指数==0 { 返回sl.GetHead () } 节点=sl.head 我:=0;i<=指数;我+ + { 节点=node.Next } 返回 } func (sl * SingleLink) pop () { popIndex:=8 delNode:=sl.Search (popIndex) fmt。Println(“流行节点:“delNode.Data) sl.DeleteByIndex (popIndex) sl.tail=sl.Search (popIndex - 1) sl.head=sl.Search (popIndex) fmt。Printf("头:% v,尾巴:% v \ n”, sl.head.Data, sl.tail.Data) } 函数main () {//初始化链表 sl:=InitSingleLink ()//生成30个元素的环 我:=0;i自己动手用Golang实现约瑟夫环算法的示例