约瑟夫问题(Josephus)链表实现

来源:互联网 发布:php urldecode解码 编辑:程序博客网 时间:2024/05/21 11:30

Josephus问题

在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3个人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。Josephus想了一个办法,帮助自己和朋友逃过了这场死亡游戏。
这里使用循环链表实现,survivor方法,参数n表示围成圈的人数(0~n-1),编号为m的人将被杀死。输出结果是被杀死人的顺序。Java代码如下:

public class Josephus {    private final int n;    private final int m;    private Node first;    private Josephus(int n, int m) {        if (n < 0 || m < 0 || n <= m)            throw new IllegalArgumentException();        this.n = n;        this.m = m;        first = new Node(0, null);        Node pre = first;        for (int i = 1; i < n; i++) {            pre.next = new Node(i, null);            pre = pre.next;        }        pre.next = first;    }    private static class Node {        int no;        Node next;        Node(int no, Node next) {            this.no = no;            this.next = next;        }    }    public static int survivor(int n, int m) {        Josephus josephus = new Josephus(n, m);        Node first = josephus.first;        while (first != first.next) {            int m0 = m;            int m1 = m - 1;            Node pre = first;            while (--m0 > 0) {            first = first.next;            }            if (m1 == 0) {                Node tail = pre;                while (pre.next != tail)                    pre = pre.next;            } else                while (--m1 > 0)                    pre = pre.next;            System.out.print(first.no + " ");`此行代码表示被杀死的人的序号            first = first.next;            pre.next = first;        }        return first.no;    }    public static void main(String[] args) {        System.out.println(Josephus.survivor(41, 3));    }}

输出结果:2 5 8 11 14 17 20 23 26 29 32 35 38 0 4 9 13 18 22 27 31 36 40 6 12 19 25 33 39 7 16 28 37 10 24 1 21 3 34 15 30

原创粉丝点击