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

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

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

  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

  2. 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:

  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) {
        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;
    }
}

Topics: Java data structure linked list