The origin of Joseph's problem, let's tell a little story first
It is said that the famous Jewish historian Josephus had the following story: after the Romans occupied jotapat, 39 Jews hid in a cave with Josephus and his friends. 39 Jews decided that they would rather die than be caught by the enemy, so they decided a way of suicide. 41 people lined up in a circle, counting from the first person. Every time they counted to the third person, they had to commit suicide, Then count off again from the next until everyone commits suicide. However, Josephus and his friends did not want to comply. Start with one person, cross the k-2 person (because the first person has been crossed), and kill the K person. Then, he crossed the k-1 man and killed the k-th man. This process continues along the circle until there is only one person left, and the person can continue to live. The question is, given and, where to stand in the first place to avoid execution. Josephus asked his friend to pretend to obey first. He arranged his friend and himself in the 16th and 31st positions, so he escaped the death game.
In short, the so-called Joseph problem is that n people form a circle, count from the person with the specified number from 1, count to m, his next count from 1, count to m, and so on until everyone is listed.
Tips
A one-way circular linked list without leading nodes is used to deal with Joseph's problem. First, a one-way circular linked list with n nodes is formed, and then count from 1 from node i. when m is counted, the corresponding node is deleted from the linked list, and then continue the above operation from the next node of the deleted node until the last node is deleted from the linked list
First create a Person node
//Create a Person class to represent a node public class Person { private int no;//number private Person next;//Point to the next node, which is null by default public Person(int no) { this.no = no; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Person getNext() { return next; } public void setNext(Person next) { this.next = next; } }
To create a one-way circular linked list:
//Create a circular one-way linked list public class CircleSingleLinkedList { //First create a first node private Person first = null; /** * Add nodes to build a circular linked list * * @param nums Number of nodes in the current linked list */ public void addBoy(int nums) { //nums does a data check if (nums < 1) { System.out.println("Wrong value!"); return; } //Create auxiliary nodes to help build a ring linked list Person curPerson = null; //Use the for loop to create a ring linked list for (int i = 1; i <= nums; i++) { //Add nodes by number Person person = new Person(i); //Judge whether it is the first node if (i == 1) { first = person; first.setNext(first);//Form a ring curPerson = first;//Let curPerson point to the first node } else { curPerson.setNext(person);//Point the next node of the current node to the newly added node person.setNext(first);//Point the next node of the newly added node to the first node to form a ring again curPerson = person;//Move secondary node back } } } /** * According to the user's input, the order of circles is calculated * * @param startNo Number of nodes from * @param countNum Count * @param nums The number of nodes in the linked list needs to be verified */ public void countBoy(int startNo, int countNum, int nums) { //Check the data first if (first == null || startNo < 1 || startNo > nums) { System.out.println("Wrong input!"); return; } //Create an auxiliary node to complete the circle out task Person helper = first; //When the while loop is out, the auxiliary node helper points to the last node while (true) { //When the next node of the auxiliary node points to the first node, it means that the auxiliary node points to the last node if (helper.getNext() == first) { break; } helper = helper.getNext();//Move the secondary node backward } //Move the first and helper startNo - 1 times before counting for (int i = 0; i < startNo - 1; i++) { first = first.getNext();//At this point, first points to the node that starts to report the number helper = helper.getNext();//At this point, the helper points to the previous node of the node that started reporting } //When counting, let the first and helper move countNum - 1 at the same time, and then circle (here is a circular operation until there is still one node in the linked list) System.out.print("The order of turning out the circle is:"); while (true) { if (helper == first) { // Indicates that there is only one node in the circle break; } for (int i = 0; i < countNum - 1; i++) { first = first.getNext(); helper = helper.getNext(); } //At this time, the node pointed to by first is the node to be circled System.out.print(first.getNo() + "->"); //At this time, the node pointed to by first is circled first = first.getNext(); helper.setNext(first); } System.out.print(+ first.getNo()); } //Traverse the current circular linked list public void showList() { //Determine whether the linked list is empty if (first == null) { System.out.println("The linked list is empty!"); return; } //Create a secondary node to help complete the traversal Person curPerson = first; System.out.print("The order of the linked list is:"); while (true) { //If the next node of the current node points to first, the traversal is completed if (curPerson.getNext() == first) { System.out.print(curPerson.getNo()); break; } System.out.print(curPerson.getNo()+"->"); curPerson = curPerson.getNext();//Move the current node back } System.out.println(); } }
The test code is as follows:
public class CircleSingleLinkedListTest { public static void main(String[] args) { CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList(); circleSingleLinkedList.addBoy(5);//Add 5 nodes circleSingleLinkedList.showList();//Print the circular linked list circleSingleLinkedList.countBoy(2,3,5);//Start counting from the second node and count one node every three times. There are 5 nodes in the linked list. } }