约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3。
分析:
(1)由于对于每个人只有死和活两种状态,因此可以用布尔型数组标记每个人的状态,可用true表示死,false表示活。
(2)开始时每个人都是活的,所以数组初值全部赋为false。
(3)模拟杀人过程,直到所有人都被杀死为止。
为了活到最后,我们只能写个算法来帮我们算了!!
思路:
- 使用循环链表
- 用一个指针,用于指向节点
- 增加一个reset方法,重置指针指向头结点
- 增加一个next方法,让指针往后走一步
- 增加一个remove方法,用于杀死指针指向的节点,删除后指向下一个节点。
public class JosephusProblem {
public static void main(String[] args) {
josephus(3,8);
}
public static void josephus(int m,int people){
CirclelinkedList list = new CirclelinkedList<>();
for (int i = 1; i <= people; i++) {
list.add(i);
}
System.out.println(list.toString());
//指向头结点
list.reset();
//循环杀
while(! list.isEmpty()){
for (int i = 1; i < m; i++) {
list.next();
}
System.out.println(list.remove());
}
}
}
package 链式结构.test; import common.AbstractList; public class CirclelinkedList{ private Node first; private Node last; private Node current; private static class Node { E element; Node prev; Node next; public Node(Node prev, E element, Node next) { this.prev = prev; this.element = element; this.next = next; } @Override public String toString() { StringBuilder sb = new StringBuilder(); if (prev != null) { sb.append(prev.element); } else { sb.append("null"); } sb.append("_").append(element).append("_"); if (next != null) { sb.append(next.element); } else { sb.append("null"); } return sb.toString(); } } public void reset(){ current = first; } public E next(){ if (current == null){ return null; } current = current.next; return current.element; } public E remove(){ if(current == null){return null;} Node next = current.next; E element = remove(current); if (size == 0) { current = null; } else { current = next; } return element; } private E remove(Node node) { if (size == 1) { first = null; last = null; } else { Node prev = node.prev; Node next = node.next; prev.next = next; next.prev = prev; if (node == first) { // index == 0 first = next; } if (node == last) { // index == size - 1 last = prev; } } size--; return node.element; } public void add(int index, E element) { rangeCheckForAdd(index); // size == 0 // index == 0 if (index == size) { // 往最后面添加元素 Node oldLast = last; last = new Node<>(oldLast, element, first); if (oldLast == null) { // 这是链表添加的第一个元素 first = last; first.next = first; first.prev = first; } else { oldLast.next = last; first.prev = last; } } else { Node next = node(index); Node prev = next.prev; Node node = new Node<>(prev, element, next); next.prev = node; prev.next = node; if (next == first) { // index == 0 first = node; } } size++; } private Node node(int index) { rangeCheck(index); if (index < (size >> 1)) { Node node = first; for (int i = 0; i < index; i++) { node = node.next; } return node; } else { Node node = last; for (int i = size - 1; i > index; i--) { node = node.prev; } return node; } }



