问题
 
设编号为1,2,… n的n个小孩围坐一圈,约定编号为k(1<=k<=n)的小孩从1开始报数,数到m的小孩出列,它的下一位又从1开始报数,数到m的小孩又出列,依次类推,直到所有小孩出列为止,由此产生一个出队编号的序列。
 
提示
 
用一个不带头结点的循环链表来处理.Joseph问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。
 
解题思路
 
第①步——创建单向循环链表
 
 
先创建第一个节点,让first指向该节点,并形成环形后面当我们每创建一个新的节点,就把该节点,加入到已有的环形链表中即可. 
第②步——设计小孩出圈要素
 
 
需求创建一个辅助指针(变量) helper,事先应该指向环形链表的最后这个节点. 补充:小孩报数前,先让first和helper移动k-1次当小孩报数时,让first和helper指针同时的移动m -1次这时就可以将first指向的小孩节点出圈 first= first.next helper.next=first 原来first指向的节点就没有任何引用,就会被回收 
代码实现
 
public class Joseph {
    public static void main(String
[] args
) {
        
        CircleSingleLinkedList circleSingleLinkedList 
= new CircleSingleLinkedList();
        circleSingleLinkedList
.addBoy(10);
        
        circleSingleLinkedList
.countBoy(3, 3, 10);
    }
}
class CircleSingleLinkedList {
    
    private Boy first 
= null
;
    
    public void addBoy(int nums
) {
        
        if (nums 
< 1) {
            System
.out
.println("nums的值不正确");
            return;
        }
        Boy curBoy 
= null
; 
        
        for (int i 
= 1; i 
<= nums
; i
++) {
            
            Boy boy 
= new Boy(i
);
            
            if (i 
== 1) {
                first 
= boy
;
                first
.setNext(first
); 
                curBoy 
= first
; 
            } else {
                curBoy
.setNext(boy
);
                boy
.setNext(first
);
                curBoy 
= boy
;
            }
        }
    }
    
    
    public void countBoy(int startNo
, int countNum
, int nums
) {
        
        if (first 
== null 
|| startNo 
< 1 || startNo 
> nums
) {
            System
.out
.println("参数输入有误, 请重新输入");
            return;
        }
        
        Boy helper 
= first
;
        
        while (true) {
            if (helper
.getNext() == first
) { 
                break;
            }
            helper 
= helper
.getNext();
        }
        
        for(int j 
= 0; j 
< startNo 
- 1; j
++) {
            first 
= first
.getNext();
            helper 
= helper
.getNext();
        }
        
        
        while(true) {
            if(helper 
== first
) { 
                break;
            }
            
            for(int j 
= 0; j 
< countNum 
- 1; j
++) {
                first 
= first
.getNext();
                helper 
= helper
.getNext();
            }
            
            System
.out
.printf("小孩%d出圈\n", first
.getNo());
            
            first 
= first
.getNext();
            helper
.setNext(first
); 
        }
        System
.out
.printf("最后留在圈中的小孩编号%d \n", first
.getNo());
    }
}
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
;
    }
}