环形链表来实现约瑟夫问题
首先我们要是实现一个环形链表
图解!
class Boy{
private int id;
private Boy next;
public Boy(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
}
class CircularLinkedList{
private Boy fist=new Boy(-1);
public void addBoy(int nums){
if(nums<1){
System.out.println("该数字不正确");
return;
}
Boy curBoy=null;
for (int i=1;i<=nums;i++){
Boy boy=new Boy(i);
if(i==1){
fist=boy;
boy.setNext(fist);
curBoy=fist;
}else {
curBoy.setNext(boy);
boy.setNext(fist);
curBoy=boy;
}
}
}
public void showBoy(){
if(fist==null){
System.out.println("链表为空");
return;
}
Boy curBoy=null;
while (true){
System.out.printf("遍历的小孩编号为=%d",curBoy.getId());
if(curBoy.getNext()==fist){
break;
}
curBoy=curBoy.getNext();
}
}
}
创建完毕环形链表之后,我们开始完成约瑟夫问题
通过图解我们来创建一个方法,来完成约瑟夫问题
/**
*
* @param starNo 第一个小孩
* @param countNum 从第几人报数
* @param nums 一共多少小孩
*/
public void countBoy(int starNo,int countNum,int nums){
if(fist==null||starNo<1||starNo>nums){
System.out.println("您输入的参数不正确");
return;
}
//设置指针让他指向头指针
Boy helper=fist;
while (true){
//如果前指针的下一个节点=头节点,则说明找到了,就退出
if(helper.getNext()==fist){
break;
}
//否则就让hepler往后走
helper=helper.getNext();
}
/**
* 如果不是从1,就把这两个指针重新定位
*
*
*
* **/
for(int j=0;j<starNo-1;j++) {
helper=helper.getNext();
fist=fist.getNext();
}
/**
* 当小孩报数是,让 fist和helper都有同时移动 m-1位
*/
while (true){
//说明只有一个节点
if(helper==fist){
break;
}
for (int j=0;j<countNum-1;j++){
helper=helper.getNext();
fist=fist.getNext();
}
System.out.printf("要出圈的小孩id是%d \n",fist.getNo());
fist=fist.getNext();
helper.setNext(fist);
}
System.out.printf("最后一个出圈的小孩的id是%d \n",helper.getNo());
}