# [data structure and algorithm] unidirectional ring linked list and Josephu ring

Posted by mvd7793 on Thu, 24 Feb 2022 19:00:53 +0100

# Josephu

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

1. 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

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:

1. Move first back k-1 times, which means starting from the k-th child
2. Move the first backward m-2 times, indicating the previous node of the m-th node to be deleted
3. Output the m-th node
4. first.next skip the m-th node and point to its next node
5. Move back first to form a new first
6. 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) {

}
}

//Create a one-way circular linked list
//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
//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) {
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;
}
}
```