package LinkedList;
/**
* @author Tan
* @version 1.0
* @email mrtanxc@163.com
* @Date 11/25/2022 1:44 PM
*/
public class JosephRingDemo {
public static void main(String[] args) {
JosephRing josephRing = new JosephRing(15);
josephRing.createJosephRing();
//josephRing.printJosephRing();
josephRing.gameStart(15, 3);
}
}
class JosephRing{
public Child first = null; //指向第一个结点
public Child last = null; //指向最后一个结点
public int numberOfChildren;
public JosephRing(int numberOfChildren) {
this.numberOfChildren = numberOfChildren;
}
//创建约瑟夫环
public void createJosephRing(){
if (!(numberOfChildren > 0)){
throw new RuntimeException("小孩的人数错啦!");
}
for (int i = 1; i <= numberOfChildren; i++) {
Child newChild = new Child(i);
//第一个孩子的next指向自己,形成环状
if (i == 1){
last = first = newChild;
first.next = first;
continue;
}
//让last始终指向最后一个小孩
last.next = newChild;
last = newChild;
last.next = first;
}
}
/**
* @param startNumber 游戏开始的编号
* @param gameOverNumber 出局的数字
*/
public void gameStart(int startNumber, int gameOverNumber){
if (!(gameOverNumber > 1) || !(startNumber > 0) || startNumber > numberOfChildren){
throw new RuntimeException("参数不正确!");
}
//把first移到编号为startNumber的小孩,把last移到first的前一个,方便删除操作
for (int i = 1; i < startNumber ; i++) {
first = first.next;
last = last.next;
}
//当first == last时,环中只剩一个小孩
while (first != last){
for (int i = 1; i <= gameOverNumber ; i++) {
//first指向要删除结点的下一个(即下一轮游戏的first)
// last为要删除结点的上一个,便于删除操作,first比last多移动一次
first = first.next;
if (i > 1){
last = last.next;
}
}
System.out.println("小孩" + last.next.childNum + "出局!");
//把last指向所在结点指向first所在结点,原last.next被垃圾回收机制清理
last.next = first;
}
System.out.println("仅剩编号为" + first.childNum + "游戏中!");
System.out.println("状态:" + first);
}
//打印约瑟夫环中的小孩
public void printJosephRing(){
Child temp = first;
do{
System.out.println(temp);
temp = temp.next;
} while (temp != first);
}
}
class Child{
public int childNum;
public Child next;
public Child(int childNum) {
this.childNum = childNum;
}
@Override
public String toString() {
return "Child{" +
"childNum=" + childNum +
", next=" + next.childNum +
'}';
}
}
运行结果如下: