Java环形链表解決约瑟夫(Joseph)问题

Posted Spring-_-Bear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java环形链表解決约瑟夫(Joseph)问题相关的知识,希望对你有一定的参考价值。

一、问题描述

约瑟夫问题:n 个人围成一圈,初始编号从 1~n 排列,从约定编号为 x 的人开始报数,数到第 m 个人出圈,接着又从出圈人的下一个人从 1 开始报数,报到第 m 个数的人又出圈,以此类推,最后圈内只剩下一个人,这个人就是赢家,求出赢家的编号。

二、实现源码

package com.bear.linkedlist;

/**
 * @author Spring-_-Bear
 * @datetime 2022/3/10 20:28
 */
public class Joseph 
    /**
     * 第一个孩子
     */
    private final ChildNode first = new ChildNode(1);
    /**
     * 孩子个数
     */
    private Integer childNums;
    /**
     * 指定要报数的数字
     */
    private Integer digit;
    /**
     * 报数开始的孩子的编号
     */
    private Integer number;

    /**
     * 开始游戏
     *
     * @param childNums 孩子个数
     * @param digit     指定要报数的数字
     * @param number    指定报数开始的孩子编号
     */
    public void startGame(int childNums, int digit, int number) 
        if (childNums < 1) 
            System.out.println("孩子个数应大于 1");
            return;
        
        if (digit < 1) 
            System.out.println("指定的报数数字应大于 1");
            return;
        
        if (number < 1) 
            System.out.println("指定报数开始的孩子的编号应大于 1");
            return;
        

        this.childNums = childNums;
        this.digit = digit;
        this.number = number;
        first.next = first;

        createChildCircle();
        startCount();
    

    /**
     * 根据孩子的个数创建环形链表
     */
    private void createChildCircle() 
        // 创建孩子节点,构建孩子环形链表
        ChildNode cur = first;
        for (int i = 2; i <= childNums; i++) 
            ChildNode childNode = new ChildNode(i);
            childNode.next = first;
            cur.next = childNode;
            cur = cur.next;
        
    

    /**
     * 根据指定的数字开始报数
     */
    private void startCount() 
        ChildNode cur = first;
        
        // 先遍历到指定开始报数的孩子处
        for (int i = 1; i < number; i++) 
            cur = cur.next;
        
        
        System.out.print("Deque order:");
        while (cur.next != cur) 
            // 获得要出队的孩子的上一个孩子的编号
            for (int i = 1; i < digit - 1; i++) 
                cur = cur.next;
            
            // 输出出队孩子的编号
            System.out.print(cur.next.getName() + "\\t");
            // 孩子出队,删除该孩子的节点
            cur.next = cur.next.next;
            // 当前指针后移,从下一个孩子开始报数
            cur = cur.next;
        
        System.out.println("\\nThe winner's number is " + cur.getName() + ".");
    

    /**
     * 打印环形链表
     */
    public void print() 
        ChildNode cur = first;
        do 
            System.out.println(cur);
            cur = cur.next;
         while (cur != first);
    

    public static void main(String[] args) 
        new Joseph().startGame(10, 3, 1);
    


class ChildNode 
    private final Integer name;
    public ChildNode next;

    public ChildNode(Integer name) 
        this.name = name;
    

    public Integer getName() 
        return name;
    

    @Override
    public String toString() 
        return "ChildNode" +
                "name='" + name + '\\'' +
                '';
    

以上是关于Java环形链表解決约瑟夫(Joseph)问题的主要内容,如果未能解决你的问题,请参考以下文章

JAVA实现: 使用单链表实现约瑟夫环(约瑟夫问题)

Day557.单向环形链表 -数据结构和算法Java

简洁明了!Java实现单向环形链表以解决约瑟夫环Josepfu问题

约瑟夫问题Java环形单向链表代码实现

Java数据结构之单向环形链表(解决Josephu约瑟夫环问题)

java代码实现经典算法约瑟夫环(环形链表法)