(Joseph U) Joseph's question:
Set n people with numbers 1, 2, 3... N to sit in a circle. It is agreed that the person with number k (1 < = k < = n) will count off from 1, and the person who counts to m will count off from 1, and the person who counts to m will list again, and the next person will count off from 1, and the person who counts to m will list again, and so on until everyone is listed, This produces a sequence of outgoing numbers.
Tip: use a ring linked list of non leading nodes to deal with the Josephu problem; First form a single cycle linked list with n nodes, and then count from 1 from node k. when m is counted, the 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.
Joseph's creation of circular linked list
The idea of constructing a one-way circular linked list
Create the first node, let first point to it, and form a ring
Later, when we create a new node, we can add the node to the existing ring linked list
Traverse circular linked list
Introduce an auxiliary pointer (variable) current, pointing to the first node
Then, through a while loop variable, the ring linked list can be current.next = first
Analysis of Joseph's out of circle thinking
According to the user's input, a circle out order is generated
n = 5, that is, there are 5 people
k = 1, counting off from the first
m = 2, number 2
- First create an auxiliary pointer (variable) helper, which should point to the last node of the ring linked list in advance.
- Before the child counts off, let the first and helper move k-1 times (in this question, K is just equal to 1, all can be moved)
- When the child counts off, let the first and helper pointers move m-1 times at the same time
- At this time, the child node pointed to by first can be circled
first = first.next
helper.next = first
The node pointed to by first has no reference and will be recycled
Turn out sequence: 2 - > 4 - > 1 - > 5 - > 3
code implementation
bean
public class JNode { private Integer num; private JNode next; public JNode(Integer num) { this.num = num; } public JNode getNext() { return next; } public void setNext(JNode next) { this.next = next; } public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } }
One way ring list method
public class SingleCircleLinkedList { //Create the first node and set the number to - 1 private JNode first = new JNode(-1); /** * Add nodes to form a ring linked list */ public void add(int nums){ //check if(nums<1){ System.out.println("At least one element was passed in"); return; } //Create a temporary node to help us build the ring list JNode current = null; //Building a one-way circular linked list for(int i=1;i<=nums;i++){ JNode node = new JNode(i); if(i==1){ first = node; first.setNext(first);//Form a ring current = first; //Let current point to the first child, and the first node cannot move }else{ current.setNext(node); node.setNext(first); current = node; } } } public void list(){ JNode current = first; if(current.getNum() == -1){ System.out.println("The current linked list is empty"); } while(true){ System.out.println("Element number:"+current.getNum()); //Move back current = current.getNext(); //Description traversal completed if(current == first){ break; } } } /** * The circle order is calculated according to the value entered by the user * @param startNo Start counting from the node * @param countNum How many times * @param num Number of nodes */ public void outCircle(int startNo,int countNum, int num){ //Verify the data first if(first.getNum() == -1|| startNo < 1||startNo>num){ System.out.println("Incorrect input parameters"); } //First create an auxiliary pointer (variable) helper, and should point to the last node of the ring linked list in advance. JNode helper = first; while(true){ if(helper.getNext()==first){ break; } helper = helper.getNext(); } //Before counting, let the first and helper move startNo-1 to the node to start counting for(int i = 0;i<startNo-1;i++){ first = first.getNext(); helper = helper.getNext(); } //When counting, let the first and helper pointers move countNum-1 times at the same time, and then circle while(true){ //When there is only one node in the circle if(helper == first){ System.out.println("Last loop node:"+first.getNum()); break; } for(int i = 0;i<countNum-1;i++){ first = first.getNext(); helper = helper.getNext(); } //Circle the node first points to System.out.println("Nodes of this circle:"+first.getNum()); first = first.getNext(); helper.setNext(first); } } }
Test code
public class Test { public static void main(String[] args) { SingleCircleLinkedList singleCircleLinkedList= new SingleCircleLinkedList(); singleCircleLinkedList.add(5); singleCircleLinkedList.list(); singleCircleLinkedList.outCircle(1,2,5); } }
Print verification