1、需求创建一个辅助指针(变量)helper,事先应该指向环形链表的最后一个节点。 补充:开始查照前,先让first和helper移动startno - 1次。
2、当开始查找时,让first和helper指针同时移动次countNum - 1次。
3、这时就可以将first指向的小孩节点出圈 first = first.next; helper.next = first; 原来的first指向的节点就没有任何引用,就会被回收。
public void countBoy(int startno,int countNum,int nums){
// startno 表示从第几个节点开始 countNum 表示数几下 nums 表示最初有几个节点在圈内
if(first == null|| startno < 1 || startno > nums){
//进行数据校验
System.out.println("您输入的参数有误");
}
//创建辅助指针,帮助完成节点出圈
boy helper = first;
//将辅助接点事先指向环形链表的最后的节点
while (true){
if(helper.getNext() == first){
break;
}
helper = helper.getNext();
}
//开始报数前,先让first和helper 移动 startno - 1 次 startno - 1表示开始数的节点
for(int j = 0 ; j < startno - 1;j++){
first = first.getNext();
helper = helper.getNext();
}
//当开始报数时,让first和helper 指针同时移动 countNum -1 次 然后出圈
//这里是一个循环操作,直到圈中还有一个节点
while (true){
if(helper == first){//说明圈中只有一个节点
break;
}
//让first和helper指针同时移动countNum - 1
for(int j = 0; j < countNum -1;j++){
first = first.getNext();
helper = helper.getNext();
}
//这时first指向的节点,就是要出圈的节点
System.out.printf("节点%d 出圈\n" ,first.getNo());
//这是将first指向的节点出圈
first = first.getNext();
helper.setNext(first);
}
System.out.printf("最后留在圈中的小孩编号%d \n",helper.getNo());
}
把环形链表创建完毕之后就可以调用这个方法来解决约瑟夫问题。