约瑟夫问题--循环链表解答(java)

约瑟夫问题,这是一个事关生命的问题。传说有一天,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]

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章