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:
-
First, create the first node, and let first point to the node to form a ring
-
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
- First let a auxiliary pointer cur point to the first node
- Then use the while loop to traverse, with the end flag: cur.next = 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
- Need a helper pointer to the last node
- Then helper and first move k-1 times to the starting child position
- Start counting and move helper, first m-1 times at the same time
- This is to let the child node pointed to by first out of the team, first=first.next;helper.next=first
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(); circleSingleLinkedList.addBoy(200); circleSingleLinkedList.showBoy(); circleSingleLinkedList.countBoy(10,3,200); } } //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"); return; } 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.setNext(boy); boy.setNext(first); 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"); return; } //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 break; } 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"); return; } //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 break; } //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(); helper.setNext(first); } 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) { this.no = no; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Boy getNext() { return next; } public void setNext(Boy next) { this.next = next; } }