自己动手用Golang实现约瑟夫环算法的示例

  

继上一篇单向链表,单线链表可以进一步扩展为环,如下图所示:

  

自己动手用Golang实现约瑟夫环算法的示例

  

特点:   

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实现约瑟夫环算法的示例