Josephu
Joseph Ring – the leading out of one-way ring linked list
Josephu's problem is: let n people with numbers 1, 2,... N sit around. It is agreed that the person with number k (1 < = k < = n) will count from 1, and the person who counts to m will be listed. Its next person will count from 1, and the person who counts to m will be listed again, and so on until everyone is listed, resulting in a sequence of out of line numbers.
Tip: use a circular linked list without leading nodes to deal with the Josephu problem: first form a single circular linked list with n nodes, and then count from 1 from node k. when m is counted, the corresponding node is deleted from the linked list, and then count from 1 from the next node of the deleted node until the last node is deleted from the linked list. The algorithm ends.
An illustration of the idea of creating a circular linked list
-
Build a one-way circular linked list
First create the first node, let the first point to the node, and form a ring
Later, when we create a new node, we can change the original tail node and the next direction of the new node to form a new ring
-
Traverse circular linked list
Let the auxiliary pointer point to the first node first
Then through the loop, move the pointer back until the pointer next==first end traversal
Illustration of children's thinking in circles
Question: circle n children. Start with the k-th child and count to the m-th child
Idea:
- Move first back k-1 times, which means starting from the k-th child
- Move the first backward m-2 times, indicating the previous node of the m-th node to be deleted
- Output the m-th node
- first.next skip the m-th node and point to its next node
- Move back first to form a new first
- The only remaining node outputs and exits the loop
Code implementation:
/* Josephu The problem is: let n people with numbers 1, 2,... N sit around and agree that the person with number k (1 < = k < = n) will count off from 1 and count to m The person who counts to m is listed again, and so on until everyone is listed Generate a sequence of outgoing numbers. */ public class Josephu { public static void main(String[] args) { CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList(); circleSingleLinkedList.add(25); // circleSingleLinkedList.out(5,1,2);//24153 circleSingleLinkedList.out(25,1,2);// } } //Create a one-way circular linked list class CircleSingleLinkedList { //Reference of the first valid node private Boy first = null; /** * n Make a circle of children, starting from the k-th child and counting to the m-th child * @param n Indicates how many children were in the circle at first * @param k It means counting from the first child * @param m It means counting */ public void out(int n,int k,int m) { if (k > n || k < 1 ||first==null) {//Data error System.out.println("The game can't be played..."); return; } //Compare K before counting, and move the variable first k-1 backward first, for (int i = 0; i < k - 1; i++) { first = first.getNext(); } while (true) { for (int i = 0; i <m-2 ; i++) { first = first.getNext();//first moves back m-2 times, indicating the previous node of the m-th node to be deleted } System.out.println("The children out of the circle are"+first.getNext().getNo()); first.setNext(first.getNext().getNext());//first.next skip the m-th node and point to its next node first = first.getNext();//Move back first if (first.getNext() == first) {//The first node itself forms a ring -- > there is only one child left on the field System.out.println("The last child out of the circle is"+first.getNo()); break; } } } //Create a linked list of n child nodes public void add(int num) { //check if (num < 1) { System.out.println("The game can't be played..."); } Boy cur=null; for (int i = 1; i <= num; i++) { Boy boy = new Boy(i); if (i == 1) {//The first child is the first and forms a ring itself first = boy; first.setNext(first); cur = first; } cur.setNext(boy);//The next of cur points to the next node cur = boy;//Iteration: cur backward cur.setNext(first);//The new next points to first to form a ring } } //ergodic public void list() { if (first == null) { System.out.println("The linked list is empty~"); return; } Boy cur=first; while (true) { System.out.println("The number of children on the field is:"+cur.getNo()); cur = cur.getNext();//cur backward if (cur ==first) {//first found, traversal is over break; } } } } class Boy { private int no; private Boy next; 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; } }