One way ring list to solve Joseph Ring problem (Java implementation)

Posted by phillfox on Fri, 06 Mar 2020 07:21:54 +0100

I. concept

One way circular list is another kind of chain storage structure. Its characteristic is that the pointer field of the last node in the table points to the head node, and the whole linked list forms a ring.

2, Joseph Ring problem

Josephus ring is a mathematical application problem: known n individuals (numbered 1, 2, 3 Sit around a round table. Count from the person whose number is k, and list the person whose number is m; count from the next person whose number is 1, and list the person whose number is m; repeat according to this rule until all the people around the round table are listed.
Problem analysis:
Firstly, the data structure used is one-way circular list to simulate round table, and the node data is int type, which represents everyone's number.

1. Initialize the circular list:

  1. First, create the first node, and let first point to the node to form a ring

  2. Then, without creating a new node, the node is added to the existing ring, and the next point of the node is first

2. How to traverse the linked list

First of all, the position of the first pointer cannot be moved, otherwise it cannot be proved that the traversal has been completed, so an auxiliary pointer is needed to help the traversal

  1. First let a auxiliary pointer cur point to the first node
  2. Then use the while loop to traverse, with the end flag: = first;

3. Analysis of children's idea of leaving the team

At this time, start to move the first. Every m-1 time the first moves, the node pointed to by the first is the child who needs to leave the queue. However, when leaving the queue, it is found that the linked list cannot be operated. Therefore, an auxiliary pointer helper is needed to help complete the operation of the child leaving the queue

  1. Need a helper pointer to the last node
  2. Then helper and first move k-1 times to the starting child position
  3. Start counting and move helper, first m-1 times at the same time
  4. This is to let the child node pointed to by first out of the team,;

3, Code implementation (including test cases)

public class Josepfu {
    public static void main(String[] args) {
        //Test to see if the build is correct
        CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();

//Create a circular one-way linked list
class CircleSingleLinkedList{
    //Create first node
    private Boy first = new Boy(-1);
    //Add child nodes and build a circular list
    public void addBoy(int nums){
        //Correctness check of nums
        if(nums < 2){
            System.out.println("Incorrect data");
        Boy cur = null;//Auxiliary pointer
        //Using for loop to create a circular list
        for (int i = 1; i <= nums; i++) {
            //Create child node according to number
            Boy boy = new Boy(i);
            //If the first child
            if(i == 1){
                first = boy;
                first.setNext(first);//Constituent rings
                cur = first;//first can't move
            }else {
                cur = boy; //Let auxiliary variable point to boy
    //Traverse the current ring list
    public void showBoy(){
        //Judge whether it is empty
        if(first == null){
            System.out.println("No children");
        //Because first cannot move, a secondary pointer is required
        Boy cur = first;
        while (true){
            System.out.printf("Child's number%d \n",cur.getNo());
            if(cur.getNext() == first){
                //Description traversal complete
            cur = cur.getNext(); //cur backward shift
    //According to the user's input, calculate the order of circles

     * @param startNo It means counting from the first child
     * @param countNum How many times
     * @param nums How many children were in the circle at first
    public void countBoy(int startNo,int countNum,int nums){
        //Verify the data first
        if(first == null || startNo < 1 || startNo > nums){
            System.out.println("Incorrect input");
        //Create auxiliary pointer
        Boy helper = first;
        while(helper.getNext() != first){
            helper = helper.getNext();
        //Move to startNo
        for (int i = 0; i < startNo - 1; i++) {
            first = first.getNext();
            helper = helper.getNext();
        //Children report, m-1
        while (true){
            if(helper == first){
                //There's only one kid in the circle
            //Moving out of circle
            for (int i = 0; i < countNum - 1; i++) {
                first = first.getNext();
                helper = helper.getNext();
            //At this point, first points to the node to be circled
            System.out.printf("Child%d Circle out\n",first.getNo());
            //Begin to circle
            first = first.getNext();
        System.out.printf("The last child left in the circle was%d\n",first.getNo());

//Create a boy class to represent a node
class Boy{
    private int no; //number
    private Boy next; //Point to next node

    public Boy(int no) { = no;

    public int getNo() {
        return no;

    public void setNo(int no) { = no;

    public Boy getNext() {
        return next;

    public void setNext(Boy next) { = next;

Welcome to my personal blog

Published 21 original articles, won praise 3, visited 562
Private letter follow