/**
* 有这样一个问题,有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