约瑟夫问题——环形链表实现

1. 约瑟夫问题

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。

2. 思路分析

采用环形链表的方式,该链表中存储first结点与cur结点,分别表示第一个人与最后一个人,其中cur.next = first,即最后一个人指向第一个人。
采取循环的方式进行,设置计数器times,当计数器等于M时,将该结点出链表,出链表的操作为:first = first.next;cur.next = first;times++;当计数器不等于M时,执行的操作仅仅为将first与cur向后移动一位,即
first = first.next; cur = cur.next; times++。

3. 图解

times = 1:
在这里插入图片描述
如图,即为环形链表的初始状态,当进行报数时,将first以及cur分别向后移动,并且将times++;

times = 2:
在这里插入图片描述如图,即为第一次移动之后的情况

times = M (即5)
在这里插入图片描述到第五个人报数之后,执行以下操作: first向后移动 cur不动并且指向新的first,旧first节点next指向空,等待垃圾回收。
在这里插入图片描述之后将times置为1,重新开始报数即可

4. 代码实现

package com.nansl.stucts.linkedList;

/**
 * 环形链表解决约瑟夫问题
 */
public class Josephu {
   
    private Boy first;
    private Boy cur;

    /**
     * 无参构造器,底下有参的是为了测试环形链表
     */
    public Josephu(){
   

    }
    public Josephu(int nums){
   

        if (nums < 1){
   
            System.out.println("男孩数量不能小于1");
            return;
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值