约瑟夫问题,这是一个事关生命的问题。传说有一天,39个犹太人躲避战乱逃到了一个洞里,洞里还有约瑟夫和他的一个朋友。犹太人呢宁死不屈,为了不让敌人抓住,于是发明了一个死亡游戏。犹太人一致决定,41个人围成一个圈,从第一个人开始数数,当数到3的那个人呢那个人就刺自己一下,把自己给杀了。比如第1个人开始数数,第3个数到3就自杀,接着第4个开始数1,第6个数到3就自杀……以此类推,直到41个人都杀掉自己。约瑟夫和他的朋友想着不能就这么轻易的go die,但是犹太人这么多他们又不能傻BB地奋起反抗。那怎么办呢,聪明的约瑟夫想到,不管自杀的顺序是怎么的,最后总会有两个人剩下。约瑟夫先生略作思考,就把自己和朋友分别排到了第16个和第31个位置,最后39个犹太人呢全都自杀了,剩下了约瑟夫和他的朋友,所有人都达到了自己的目的,皆大欢喜(虽然有点血腥,但是约瑟夫凭借自己的智慧活了下来)。
import com.sun.nio.sctp.IllegalReceiveException;
public class YueshefuLinked<E> {
private class Node{
public E e;
public Node next;
public Node() {
this(null, null);
}
public Node(E e) {
this(e, null);
}
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
}
private Node head;
private int size;
public YueshefuLinked() {
this.head = null;
this.size = 0;
}
public int getSize() {
return size;
}
public void add(int index, E e) {
if (index < 0 || index > size) {
throw new IllegalReceiveException("add fail. index is illegal");
}
if (head == null) {
head = new Node(e);
head.next = head;
size++;
return;
}
if (index == 0) {
addFirst(e);
} else {
Node cur = head;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
Node newNode = new Node(e, cur.next);
cur.next = newNode;
size++;
}
}
public void addFirst(E e) {
if (head == null) {
head = new Node(e);
head.next = head;
size++;
return;
}
Node cur = head;
for (int i = 0; i < size - 1; i++) {
cur = cur.next;
}
Node newNode = new Node(e, head);
cur.next = newNode;
head = newNode;
size++;
}
public void remove(int index) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("remove fail. idnex is illegal");
}
if (head == null) {
throw new IllegalArgumentException("remove fail. linked is empty");
}
if (index == 0) {
removeFirst();
} else {
Node cur = head;
for (int i = 0; i < index - 1; i++) {
cur = cur.next;
}
Node rnode = cur.next;
cur.next = rnode.next;
size--;
}
}
public void removeFirst() {
if (head == null) {
throw new IllegalArgumentException("remove fail. linked is empty");
}
if (size == 1) {
head = null;
size--;
} else {
Node cur = head;
for (int i = 0; i < size; i++) {
cur = cur.next;
}
head = head.next;
cur.next = head;
size--;
}
}
/** 约瑟夫问题
* 首先自定义了一个循环链表
*/
public void checkYueshefu() {
Node cur = head;
int i = 1;
while (true) {
if (i == 2) {
Node next = cur.next;
cur.next = next.next;
/*要记住把head的指向改变,不然会一直重1开始打印。*/
head = cur;
i = 0;
size--;
}
i++;
cur = cur.next;
if (size < 3) {
break;
}
}
System.out.println(toString());
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append(String.format("YueshefuLinked: size = %d, [", size));
Node cur = head;
for (int i = 0; i < size; i++) {
str.append(cur.e + "->");
cur = cur.next;
}
str.append(cur.e);
str.append("]");
return str.toString();
}
}
@Test public void test_yueshefu() { YueshefuLinked<Integer> linked = new YueshefuLinked(); for (int i = 41; i > 0; i--) { linked.addFirst(i); } System.out.println("循环49次以后:" + linked); linked.checkYueshefu(); //YueshefuLinked: size = 2, [31->16->31]
}