Java 循环链表实现约瑟夫问题

package LinkedList;

/**
 * @author Tan
 * @version 1.0
 * @email mrtanxc@163.com
 * @Date 11/25/2022 1:44 PM
 */
public class JosephRingDemo {
    public static void main(String[] args) {
        JosephRing josephRing = new JosephRing(15);
        josephRing.createJosephRing();
        //josephRing.printJosephRing();
        josephRing.gameStart(15, 3);
    }
}

class JosephRing{

    public Child first = null; //指向第一个结点
    public Child last = null; //指向最后一个结点
    public int numberOfChildren;

    public JosephRing(int numberOfChildren) {
        this.numberOfChildren = numberOfChildren;
    }

    //创建约瑟夫环
    public void createJosephRing(){
        if (!(numberOfChildren > 0)){
            throw new RuntimeException("小孩的人数错啦!");
        }
        for (int i = 1; i <= numberOfChildren; i++) {
        	Child newChild = new Child(i);
            //第一个孩子的next指向自己,形成环状
            if (i == 1){
                last = first = newChild;
                first.next = first;
                continue;
            }
            //让last始终指向最后一个小孩
            last.next = newChild;
            last = newChild;
            last.next = first;
        }
    }

    /**
     * @param startNumber 游戏开始的编号
     * @param gameOverNumber 出局的数字
     */
    public void gameStart(int startNumber, int gameOverNumber){
        if (!(gameOverNumber > 1) || !(startNumber > 0) || startNumber > numberOfChildren){
            throw new RuntimeException("参数不正确!");
        }
        //把first移到编号为startNumber的小孩,把last移到first的前一个,方便删除操作
        for (int i = 1; i < startNumber ; i++) {
            first = first.next;
            last = last.next;
        }
        //当first == last时,环中只剩一个小孩
        while (first != last){
            for (int i = 1; i <= gameOverNumber ; i++) {
                //first指向要删除结点的下一个(即下一轮游戏的first)
                // last为要删除结点的上一个,便于删除操作,first比last多移动一次
                first = first.next;
                if (i > 1){
                    last = last.next;
                }
            }
            System.out.println("小孩" + last.next.childNum + "出局!");
            //把last指向所在结点指向first所在结点,原last.next被垃圾回收机制清理
            last.next = first;
        }
        System.out.println("仅剩编号为" + first.childNum + "游戏中!");
        System.out.println("状态:" + first);
    }

    //打印约瑟夫环中的小孩
    public void printJosephRing(){
        Child temp = first;
        do{
            System.out.println(temp);
            temp = temp.next;
        } while (temp != first);
    }
}

class Child{
    public int childNum;
    public Child next;

    public Child(int childNum) {
        this.childNum = childNum;
    }

    @Override
    public String toString() {
        return "Child{" +
                "childNum=" + childNum +
                ", next=" + next.childNum +
                '}';
    }
}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值