josephe约瑟夫问题-使用环形链表解决问题

本文探讨了约瑟夫问题的经典解决方案,通过构建环形链表模拟游戏过程,详细介绍了环形链表的定义、实现及如何用其解决约瑟夫问题,展示了完整的Java代码实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

josephe约瑟夫问题-使用环形链表解决问题

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,S=1,被杀掉的顺序是:5,4,6,2,3,1。(N为该总人数,M为数的对应的人出列,S为开始的编号)。
环形链表的结构如下所示:
在这里插入图片描述

public class Person {//定义一个节点
    private int no;//定义一个编号
    private Person next;//指针

    public void setNo(int no) {
        this.no = no;
    }

    public void setNext(Person next) {
        this.next = next;
    }

    public int getNo() {
        return no;
    }

    public Person getNext() {
        return next;
    }
    public Person(int no){//有参构造函数初始化,将学号初始化
        this.no=no;
    }
}

定义一个链表,链表结构如下:

public class CilcleSingleLinkList {
   private Person First=null;//定义一个头指针
   
  //添加函数
  /**
  *@nums 人的个数
  */
   public void add(int nums){
       //判断输入的人数是否符合实际情况
       if(nums<1){
           System.out.println("nums的值不正确");
           return;
       }
       Person curBoy=null;
       for (int i=1;i<=nums;i++){
           Person boy=new Person(i);
           if (i==1){
               First=boy;
               First.setNext(First);
               curBoy=First;
           }else{
               curBoy.setNext(boy);
               boy.setNext(First);
               curBoy=boy;
           }
       }
   }

   public void list(){
       if(First==null){
           System.out.println("链表为空");
           return;
       }
       Person curBoy=First;
      while (true){
          System.out.println("小孩的编号:"+curBoy.getNo());
          if (curBoy.getNext()==First){
              break;
          }
          curBoy=curBoy.getNext();
      }
   }

    /**
     *
     * @param startBoy  开始的数数的小孩
     * @param countnum  表示数几下出队
     * @param nums   最初由多少小孩在环形单链表中
     */
   public void CountBoy(int startBoy,int countnum,int nums){
       if(First==null || startBoy<1 || startBoy>nums){
           System.out.println("参数输入有误,请重新输入");
           return;
       }
       Person helper=First;
       while (true){
           if (helper.getNext()==First){
               break;
           }
           helper=helper.getNext();
       }
       for (int j=0;j<startBoy-1;j++){
           First=First.getNext();
           helper=helper.getNext();
       }
       while (true){
           if(helper==First){
               break;
           }
           for(int i=0;i<countnum-1;i++){
               First=First.getNext();
               helper=helper.getNext();
           }
           System.out.println("出圈的小孩为:"+First.getNo());
           First=First.getNext();
           helper.setNext(First);
       }
       System.out.println("出圈的小孩为:"+First.getNo());
   }
}

```java
public class CilcleSingleLinkListDemo {
    public static void main(String[] args) {
        CilcleSingleLinkList cilcleSingleLinkList=new CilcleSingleLinkList();
        cilcleSingleLinkList.add(5);
        cilcleSingleLinkList.list();

        //出圈的顺序
        cilcleSingleLinkList.CountBoy(1,3,5);
    }
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr丶李先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值