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 +
                '}';
    }
}

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


版权声明:本文为weixin_44720549原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。