据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
环形链表实现思路:
1.创建一个工具节点tool。
2.通过for循环创建链表,创建第一个节点first=new node,tool最开始先指向first
3.新添节点时tool.next=new node
4.新添节点的next指向链表头部节点first tool.next.next=first
5.将tool节点后移(需要让tool节点指向链表的最后一个节点来完成在末尾添加节点的操作)
约瑟夫问题解决思路:
1.first移动到num节点的下一个节点位置。first移动到从当前位置数数第num+1个位置
2.rear移动到num节点的上一个节点位置。rear移动到从当前位置数数第num个位置
3.rear.next=first来删除num节点
public class CircularLinkedListTest {
public static void main(String[] args) {
CircularLinkedList circularLinkedList=new CircularLinkedList(7);
circularLinkedList.josephRing(1,2);
}
}
//管理链表
class CircularLinkedList{
private int maxSize;
private Node first;
//初始化环形链表
public CircularLinkedList(int maxSize){
this.maxSize=maxSize;
Node tool=null;
for (int i=1;i<=maxSize;i++){
if (i==1){
first=new Node(1);
tool=first;
}else {
tool.next=new Node(i);
tool.next.next=first;
tool=tool.next;
}
System.out.println("第"+tool.number+"个小孩入圈");
}
}
public void josephRing(int start,int num){
Node rear=first;
for (int i=1;i<maxSize;i++){
rear=rear.next;
}
if (first==rear){
System.out.println("最后一个小孩为"+first.number);
return;
}
while (true){
for (int i=1;i<start;i++){
first=first.next;
rear=rear.next;
}
for (int i=1;i<=num+1;i++){
first=first.next;
}
for (int i=1;i<=num;i++){
rear=rear.next;
}
System.out.println("第"+rear.next.number+"个小孩出圈");
rear.next=first;
if (first==rear){
System.out.println("最后一个小孩为"+first.number);
return;
}
}
}
}
//声明节点
class Node{
Node next;
int number;
public Node(int number){
this.number=number;
}
@Override
public String toString() {
return "Node{" +
"number=" + number +
'}';
}
}