約瑟夫問題--循環鏈表解答(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]

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