约瑟夫环实现

约瑟夫环

约瑟夫环小游戏:把小朋友按照编号1,2,3,...,n围成一圈,指定编号为k的小朋友从1开始报数,数到m的小朋友出队。接着他的下一位小朋友再次从1报数,以此类推,直到所有人都出队,产生了一个出队编号的序列。

  1. 代码实现
java 复制代码
public class Josepfu {
    
    public static void main(String[] args) {
        CircleLinkList list = new CircleLinkList();
        list.addBoy(10);
        list.show();
        list.countBoy(2, 4, 10);
    }
    
    /**
     * 使用环形链表模拟约瑟夫环
     */
    private static class CircleLinkList {
        //创建头结点
        private Boy first;
        
        /**
         * 添加节点形成链表
         * @param nums 小朋友的人数
         */
        void addBoys(int nums) {
            if (nums < 1) {
                System.out.println("nums的值不正确");
                return;
            }
            
            //添加辅助节点
            Boy current = null;
            for (int i=1;i<=nums;i++) {
                Boy boy = new Boy(i);
                if (i == 1) {
                    //第一个小朋友形成自环
                    first = boy;
                    first.next = first;
                    current = first;
                } else {
                    current.next = boy;
                    boy.next = first;
                    current = current.next;
                }
            }
        }
        
        /**
         * 报数
         * @param startNo 从第几个小孩报数
         * @param countNum 表示数到几号出队
         * @param nums 圈中小孩的数目
         */
        void countBoy(int startNo, int countNum, int nums){
            if (first == null || startNo < 1 || startNo > countNum) {
                System.out.println("输入参数有误,重新输入");
                return;
            }
            
            //使用辅助节点指向链表末尾
			Boy helper = first;
            while(helper.next != first) {
                helper = helper.next;
            }
            
            //小朋友报数前把first和helper移动到开始报数的小朋友的位置
            for (int i=0;i<startNo-1;i++) {
                first = first.next;
                helper = helper.next;
            }
            
            //当小朋友报数时,移动m-1次后出圈
            while (true) {
                if (first == helper) {
                    break;
                }
                
                for (int j=0;j<countNum-1;j++) {
                    first = first.next;
                    helper = helper.next;
                }
                
                //first指向要出圈的节点
                System.out.printf("小朋友%d出圈\n", first.no);
                first = first.next;
                helper.next = first;
            }
            System.out.println("最后留在圈中的小朋友编号是:" + first.no);
        }
        
        /**
         * 显示链表中的小朋友
         */
        void show() {
            if (first == null) {
                System.out.println("链表为空");
                return;
            }
            
            Boy current = first;
            while(true){
                System.out.printf("小朋友的编号%d\n", current.no);
                if(current.next == first){
                    break;
                }
                current = current.next;
            }
        }               
    }
    
    /**
     * 小朋友
     */
    private static class Boy {
        int no;
        Boy next;
        
        Boy(int no) {
            this.no = no;
        }
    }
}
  1. 以10个小朋友,从第2号小朋友开始从1报数,数到4出圈为例,输出结果如下:

小朋友的编号8

小朋友的编号9

小朋友的编号10

小朋友5出圈

小朋友9出圈

小朋友3出圈

小朋友8出圈

小朋友4出圈

小朋友1出圈

小朋友10出圈

小朋友2出圈

小朋友7出圈

最后留在圈中的小朋友编号是:6

相关推荐
前端炒粉3 小时前
18.矩阵置零(原地算法)
javascript·线性代数·算法·矩阵
im_AMBER3 小时前
数据结构 09 二叉树作业
数据结构·笔记·学习
暴风鱼划水3 小时前
三维重建【0-D】3D Gaussian Splatting:相机标定原理与步骤
算法·3d
l1t5 小时前
利用DeepSeek修改数据结构提升求解集合程序效率
数据结构·python·deepseek
mount_myj6 小时前
敏感信息屏蔽(一)【java】
java·算法·极课堂
先做个垃圾出来………6 小时前
偏移量解释
数据结构·算法
FanXing_zl6 小时前
基于整数MCU的FOC控制定标策略深度解析
单片机·嵌入式硬件·mcu·算法·定点运算·q15
立志成为大牛的小牛7 小时前
数据结构——三十三、Dijkstra算法(王道408)
数据结构·笔记·学习·考研·算法·图论
地平线开发者8 小时前
mul 与 reduce_sum 的优化实例
算法·自动驾驶