约瑟夫问题(Josephus problem)详解

约瑟夫问题

1)设编号为 1,2,3 ... n 的 n 个人围坐一圈。

2)约定编号为 k (1 <= k <= n)的人从 1 开始报数,数到 m 的那个人出列。

3)它的下一位又从 1 开始报数,数到 m 的那个人又出列,依此类推,直到所有人出列为止。

4)由此产生一个出列编号的序列。

解题思路

1)构建一个结构体 Boy

    No 为 Boy 的编号。

    Next 指针指向下一个 Boy。

代码如下:

// 小孩的结构体
type Boy struct {
	No   int  // 编号
	Next *Boy // 指向下一个小孩的指针
}

2)根据编号,创建一个单向环形队列。

假设 n = 5 ,即一共圈内有5个小孩,创建完成的结构体如图所示:

first 指针指向队首。

curBoy 指针指向当前要添加的新节点。

当只有一个小孩时,构成一个自循环,Next 指针指向自身,如图所示:

当不止一个小孩,新节点加入的流程如图所示:

1、构建编号为 n 的新节点 boy

boy := &Boy{
	No: i,
}

2、循环加入编号为 n 的新节点:

让 curBoy 的 Next 指针指向新建立的节点 boy

让 curBoy 指针指向新建立的节点 boy 

让 curBoy 的 Next 指针指向头节点 first

依此类推,循环加入新节点

如图所示:

  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值