List (Linked List): a unidirectional ring list

List describes unidirectional ring

  • Josephu (Josephus, Josephus) issues

   Provided numbered 1,2,3, n ...... individuals sitting around the n-agreed number k (1 <= k <= n) of the number of packets from the beginning person, that person to the number m of the columns, it's gettin next and from one number to the number m of that person and out of the column, and so on, until everyone out of the line up, thereby generating a sequence number of the team.

  • prompt

   An endless chain to deal with the lead node Josephu issues: first list constituting a single cycle of n nodes, and then starts counting from the node k, the chronograph to m, corresponding to the node removed from the list, and then from node 1 is deleted and from the start counting until the last node to delete from the list algorithm ends.

  • Schematic Josephu problem

  • Joseph problem - the idea to create a circular linked list illustration

    Construction of a one-way circular linked list ideas

      1. First create the first node, so that points to the first node, and an annular

      2. When we back each create a new node, put the node is added to the list to an existing ring

    Circular linked list traversal

      1. Allow an auxiliary pointer (variable) curBoy, pointing first node

      2. The circular linked list is then traversed through a while loop to curBoy.next == first end

  • Joseph problems - a child laps ideas analysis chart

    Based on user input, generating a ring sequence of a child

    n = 5, i.e., five individual

    k = 1, the number of packets from the first person begins

    m = 2, the number 2

 

    1. Create a demand for auxiliary pointer (variable) helper, prior to this last point should ring node list.

    Added: the number of children reported before, let the first move and helper k - 1 times

    2. When the number of packets children, and let m first helper pointer moving simultaneously - 1 x

    3. Then you can point to the first child node of the ring

    first = first .next

    helper.next = first

    原来first 指向的节点就没有任何引用,就会被回收

 

    出圈的顺序 2->4->1->5->3

  • 约瑟夫问题的代码实现

  1 package com.jyj.linkedList;
  2 
  3 public class Josephu {
  4     public static void main(String[] args) {
  5         CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
  6         circleSingleLinkedList.addBoy(5);
  7         circleSingleLinkedList.showBoy();
  8         //测试小孩出圈顺序
  9         circleSingleLinkedList.countBoy(1, 2, 5);
 10     }
 11 }
 12 
 13 //创建一个环形的单向链表
 14 class CircleSingleLinkedList {
 15     //创建一个first节点,当前没有编号
 16     private Boy first = new Boy(-1);
 17     
 18     //添加小孩节点,构成环形链表
 19     public void addBoy(int nums) {
 20         //nums 做一个数据校验
 21         if(nums < 1) {
 22             System.out.println("nums 值不正确");
 23             return;
 24         }
 25         Boy curBoy = null; //辅助指针,帮助构建环形链表
 26         //使用for来创建我们的环形链表
 27         for(int i = 1;i <= nums;i++) {
 28             //根据编号,创建小孩节点
 29             Boy boy = new Boy(i);
 30             //如果是第一个小孩
 31             if(i == 1) {
 32                 first = boy;
 33                 first.setNext(first);
 34                 curBoy = first;
 35             } else {
 36                 curBoy.setNext(boy);
 37                 boy.setNext(first);
 38                 curBoy = boy;
 39             }
 40         }
 41     }
 42     
 43     //遍历当前的单向环形链表
 44     public void showBoy() {
 45         //判空
 46         if(first == null) {
 47             System.out.println("链表为空,没有任何小孩~");
 48             return;
 49         }
 50         //因为first不能动,定义辅助指针
 51         Boy curBoy = first;
 52         while(true) {
 53             System.out.printf("小孩的编号 %d\n", curBoy.getNo());
 54             if(curBoy.getNext() == first) { //遍历完毕
 55                 break;
 56             }
 57             curBoy = curBoy.getNext(); //curBoy后移
 58         }
 59     }
 60     
 61     //根据用户输入,计算小孩出圈顺序
 62     /**
 63      * 
 64      * @param startNo 表示从第几个小孩开始数数
 65      * @param countNo 表示数几下
 66      * @param nums 表示最初有多少小孩在圈中
 67      */
 68     public void countBoy(int startNo,int countNo,int nums) {
 69         //数据校验
 70         if(first == null || startNo < 1 || startNo > nums) {
 71             System.out.println("参数不正,请重新输入");
 72             return;
 73         }
 74         //创建辅助指针(变量)helper,事先应该指向环形链表的最后这个节点。
 75         Boy helper = first;
 76         while(true) {
 77             if(helper.getNext() == first) {//helper 是最后一个节点
 78                 break;
 79             }
 80             helper = helper.getNext();
 81         }
 82         //小孩报数前,先让first 和 helper移动 startNo-1 次
 83         for(int i = 0;i < startNo - 1;i++) {
 84             first = first.getNext();
 85             helper = helper.getNext();
 86         }
 87         while(true) {
 88             if(first == helper) {//剩最后一个节点
 89                 break;
 90             }
 91             //小孩报数时,让first 和 helper指针同时的移动 countNo - 1 次
 92             for(int i = 0;i < countNo - 1;i++) {
 93                 first = first.getNext();
 94                 helper = helper.getNext();
 95             }
 96             System.out.printf("小孩编号 %d 出圈\n", first.getNo());
 97             first = first.getNext();
 98             helper.setNext(first);
 99         }
100         System.out.printf("最后一个小孩的编号是first : %d,helper : %d\n", first.getNo(),helper.getNo());
101     }
102 }
103 
104 //创建一个Boy类,表示一个节点
105 class Boy {
106     private int no;//编号
107     private Boy next;//指向下一个节点,默认为null
108     public Boy(int no) {
109         this.no = no;
110     }
111     public int getNo() {
112         return no;
113     }
114     public void setNo(int no) {
115         this.no = no;
116     }
117     public Boy getNext() {
118         return next;
119     }
120     public void setNext(Boy next) {
121         this.next = next;
122     }
123 }
View Code

以上

Guess you like

Origin www.cnblogs.com/jianyingjie/p/12169091.html