約瑟夫問題大意:
在羅馬人佔領喬塔帕特後,39個猶太人與約瑟夫及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡爲止。然而約瑟夫和他的朋友並不想遵從,約瑟夫要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。
循環鏈表解法:
public class JosephTest {
/**
* 記錄首節點
*/
private Node first;
/**
* 記錄前一個節點
*/
private Node pre;
public static void main(String[] args) {
JosephTest josephTest = new JosephTest();
josephTest.joseph(josephTest);
}
public void joseph(JosephTest josephTest) {
josephTest.createCircleList(41);
Node node = josephTest.first;// 當前節點,初始爲首節點
Node next = null;// 當前節點的下一節點
Node before = null;// 當前節點的上一節點
int count = 1;// 初始爲1,因爲上面已經node賦值爲first了
/**
* 當全部kill掉所有報數=3的人後,僅剩2個元素的時候走進count==3中
* node.next = next.next = node 如此結束循環
*/
while (node != node.getNext()) {
if (count == 3) {
/**
* node節點置爲上一節點,並將上一節點的下節點置爲next(也就是死掉節點)的下節點
*/
node = before;
node.setNext(next.getNext());
count = 0;
} else {
/**
* 1.before暫存當前節點
* 2.next存儲當前節點的下一節點
* 3.當前節點置爲next成爲下一循環的當前節點
* 4.count+1
*/
before = node;
next = node.getNext();
node = next;
count++;
}
}
System.out.println(node.getItem());
System.out.println(node.getNext().getItem());
System.out.println(next.getItem());
}
@Test
public void testCircleList() {
JosephTest josephTest = new JosephTest();
josephTest.createCircleList(8);
Node node = josephTest.first;
Node next = null;
for (int i = 0; i < 43; i++) {
next = node.getNext();
node = next;
if (next != null) {
System.out.println(next.getItem());
}
}
}
// 創建循環鏈表
public void createCircleList(int n) {
for (int i = 1; i <= n; i++) {
// 首節點
if (i == 1) {
first = new Node(i, null);
pre = first;
continue;
}
// 尾節點的下一個節點指向首節點即可構成循環鏈表
if (i == n) {
Node tail = new Node(n, first);
pre.setNext(tail);
continue;
}
Node newNode = new Node(i, null);
pre.setNext(newNode);
pre = newNode;
}
}
}
public class Node<T> {
/**
* 下一個節點
*/
private Node next;
/**
* 數據
*/
private T item;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public T getItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
}