约瑟夫josephu问题 GO 单向环形链表实现

josephu问题 n(num)个男孩围一圈,从1数到m,第m个孩子出列,下一个接着从1,依次类推,设出列k个孩子,由此产生一个出队编号的序列

package main	//韩磊   201916010619
import (
	"fmt"
)
//小孩的结构体
type Boy struct {
	No int // 编号
	Next *Boy // 指向下一个小孩的指针[默认值是nil]
}

// 编写一个函数,构成单向的环形链表
// num :表示小孩的个数
// *Boy : 返回该环形的链表的第一个小孩的指针
func AddBoy(num int) *Boy {
	first := &Boy{
		No : 1,
	} //初始结点
    this := first //替身
	for i := 2; i <= num; i++ {
		boy := &Boy{
			No : i,
		//	boy.Next : first
//链表是固定的,不必使新元素初始时就指向开头
		}
		this.Next = boy //连新的元素
		this = boy	//迭代替身
	}
	this.Next = first //最后一个串联第一个
	return first
}

//显示单向的环形链表[遍历]
func ShowBoy(first *Boy) {
	//处理一下如果环形链表为空
	if first.Next == nil {
		fmt.Println("链表为空,没有小孩...")
		return
	}

	//创建一个指针,帮助遍历.[说明至少有一个小孩]
	this := first  
	for {
		fmt.Printf("小孩编号=%d ->", this.No)
		if this.Next == first {
			fmt.Println()
			break
		}
		this = this.Next //迭代
	}
}
					// 从1数到m, 出列k个孩子  k <= num
func PlayGame(first *Boy, m int, k int) {
	if first.Next == nil {
		fmt.Println("空的链表,没有小孩")
		return
	}
	fmt.Printf("\n出队编号的序列: \n")
	this := first  
	t := first  
	for j := 1; j <= k; j++ {
		for i := 1; i < m; i++ { //k=1时,此for跳过
			t = this  // t 作为this前一个元素
		//	fmt.Println("t:", t.No)
			this = this.Next
		//	fmt.Println("this:", this.No)
		}
		//出列
		fmt.Printf("编号%d 出列\n", this.No)
		t.Next = this.Next  //this前一个指向后一个
		this = this.Next //this 变成后一个
	}
}

func main() {
	first := AddBoy(5)
	//显示
	ShowBoy(first)
	PlayGame(first, 3, 5)
}

输出:(版本1)
小孩编号=1 ->小孩编号=2 ->小孩编号=3 ->小孩编号=4 ->小孩编号=5 ->

出队编号的序列:
编号3 出列
编号1 出列
编号5 出列
编号2 出列
编号4 出列

(版本2)
小孩编号=1 ->小孩编号=2 ->小孩编号=3 ->小孩编号=4 ->小孩编号=5 ->

出队编号的序列:
t: 1
this: 2
t: 2
this: 3
编号3 出列
t: 4
this: 5
t: 5
this: 1
编号1 出列
t: 2
this: 4
t: 4
this: 5
编号5 出列
t: 2
this: 4
t: 4
this: 2
编号2 出列
t: 4
this: 4
t: 4
this: 4
编号4 出列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值