约瑟夫问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。
人们站在一个等待被处决的圈子里。 计数从圆圈中的指定点开始,并沿指定方向围绕圆圈进行。 在跳过指定数量的人之后,执行下一个人。 对剩下的人重复该过程,从下一个人开始,朝同一方向跳过相同数量的人,直到只剩下一个人,并被释放。
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号