約瑟夫問題(有時也稱爲約瑟夫斯置換),是一個出現在計算機科學和數學中的問題。在計算機編程的算法中,類似問題又稱爲約瑟夫環。
人們站在一個等待被處決的圈子裏。 計數從圓圈中的指定點開始,並沿指定方向圍繞圓圈進行。 在跳過指定數量的人之後,執行下一個人。 對剩下的人重複該過程,從下一個人開始,朝同一方向跳過相同數量的人,直到只剩下一個人,並被釋放。
public class Node {
int value;
Node next;
public Node(int value) {
this.value = value;
}
}
public class TestJoseph {
// 創建鏈表
public static Node createLinkList(int n) {
Node head = new Node(1);
Node pre = head;
for (int i = 2; i < n + 1; i++) {
Node newNode = new Node(i);
pre.next = newNode;
pre = newNode;
pre.next = head;
}
return head;
}
// 打印鏈表
public static void printLink(Node root) {
StringBuilder out = new StringBuilder();
Node cur = root;
while (true) {
out.append(cur.value).append(" ");
if (cur.next == null || cur.next == root) {
break;
}
cur = cur.next;
}
System.out.println(out);
}
public static void main(String[] args) {
// 等待處決的人的個數
int n = 5;
// 計數點
int m = 2;
// 如果是1的話,特殊處理,直接輸出
if (m == 1) {
System.out.println(n);
} else {
Node head = createLinkList(n);
printLink(head);
Node pre = null;
Node cur = head;
// 終止條件是節點的下一個節點指向本身
while (cur.next != cur) {
for (int i = 0; i < m - 1; i++) {
pre = cur;
cur = cur.next;
}
pre.next = cur.next;
cur.next = null;
cur = pre.next;
printLink(cur);
}
}
}
}
1 2 3 4 5
3 4 5 1
5 1 3
3 5
3
5個人組成圓環,第一次殺掉第二個人
從上一次殺掉的人的下一個開始組成新圓環,依然殺掉第二個人
…
直至剩下最初五人的3號