约瑟夫问题--->环形链表

/**
 * 有这样一个问题,有N个人围成一圈做游戏,编号为1->2->3->...->1,
 * 让第m个人开始报数,报到底k个数的那个人出队,出队的下一个人继续报数,
 * 报到第k个数的人再出队。。。以此类推,求出最后一个出队的人。
 */
public class JosephusProblem {
    public static void main(String[] args) {
        CycleLink cyc = new CycleLink();
        cyc.createLink(8);
        cyc.show();
        cyc.play(2, 2, 8);
    }
}
class CycleLink{
    private Boy firstBoy;
    //创建环形链表
    public void createLink(int length){
        if(length<1){
            System.out.println("人数不得少于一个");
            return;
        }else if(length==1){
            firstBoy  = new Boy(1);
            firstBoy.setNext(firstBoy);
        }else{
            Boy temp = null;
            for (int i = 1; i <= length; i++) { //报数的时候从一报 循环的时候从1开始
                Boy bo = new Boy(i);//链表头也是从1开始
                if(i==1){ //确定第一个,和中间量的值
                    firstBoy = bo;
                    temp = bo;
                }else if(i==length){ 
                    temp.setNext(bo); //给上一个boy指定指向
                    temp = bo;
                    temp.setNext(firstBoy); //把最后一个指向第一个
                }else{
                    temp.setNext(bo);
                    temp = bo;
                }
            }
        }
    }
    /**
     * 开始测试
     * @param startNo 第几个开始报数
     * @param ksize  报数报到多少
     * @param countSzie 总人数
     */
    public void play(int startNo,int ksize,int countSzie){
        if(firstBoy==null || startNo<=0 || startNo>countSzie){
            System.out.println("链表有误,请重新校验");
            return;
        }
        int k = 1;
        Boy temp = null;
        while(true){
            if(k == (ksize+startNo-1)){
                System.out.print(firstBoy.getNo()+"	");
                startNo=0;
                k=0;  //取出一个后 重置k
                if(firstBoy.equals(firstBoy.getNext())){
                    break;
                }else{
                    temp.setNext(firstBoy.getNext());  //需要取出当前boy的时候 把上一个指向 下一个
                    firstBoy = firstBoy.getNext();  //指向下一个
                    continue;
                }
            }
            temp = firstBoy; //下一次遍历的时候 充当上一个
            firstBoy = firstBoy.getNext();
            k++;
        }
    }
    //显示链表
    public void show(){
        Boy temp = firstBoy;
        
        if(firstBoy==null){
            System.out.println("链表为空。。");
            return;
        }
        while(true){
            System.out.print(firstBoy.getNo()+"	");
            firstBoy = firstBoy.getNext();
            if(temp.equals(firstBoy)){
                break;
            }
        }
        System.out.println();
    }
    public Boy getFirstBoy() {
        return firstBoy;
    }
    public void setFirstBoy(Boy firstBoy) {
        this.firstBoy = firstBoy;
    }
    
    
}
class Boy{
    private int no; //编号
    private Boy next; //下一个
    
    public Boy() {
    }
    
    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;
    }
    
}
打印:
1    2    3    4    5    6    7    8    
3    5    7    1    4    8    6    2    
原文地址:https://www.cnblogs.com/cai170221/p/13500581.html