约瑟夫环实现

约瑟夫环

约瑟夫环小游戏:把小朋友按照编号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

相关推荐
hweiyu0013 分钟前
数据结构和算法分类
数据结构·算法·分类
M K Q15 分钟前
2025.9 GESP三级 日历制作
算法
AI小云18 分钟前
【数据操作与可视化】Pandas数据处理-Series数据结构
开发语言·数据结构·python·numpy·pandas
x***J34831 分钟前
算法竞赛训练方法
算法
前端小L33 分钟前
图论专题(十六):“依赖”的死结——用拓扑排序攻克「课程表」
数据结构·算法·深度优先·图论·宽度优先
前端小L34 分钟前
图论专题(十三):“边界”的救赎——逆向思维解救「被围绕的区域」
数据结构·算法·深度优先·图论
风筝在晴天搁浅39 分钟前
代码随想录 738.单调递增的数字
数据结构·算法
Miraitowa_cheems1 小时前
LeetCode算法日记 - Day 108: 01背包
数据结构·算法·leetcode·深度优先·动态规划
大千AI助手1 小时前
平衡二叉树:机器学习中高效数据组织的基石
数据结构·人工智能·机器学习·二叉树·大模型·平衡二叉树·大千ai助手
九年义务漏网鲨鱼1 小时前
【多模态大模型面经】现代大模型架构(一): 组注意力机制(GQA)和 RMSNorm
人工智能·深度学习·算法·架构·大模型·强化学习