約瑟夫問題:循環鏈表

約瑟夫問題大意:

在羅馬人佔領喬塔帕特後,39個猶太人與約瑟夫及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡爲止。然而約瑟夫和他的朋友並不想遵從,約瑟夫要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。

循環鏈表解法:

public class JosephTest {

    /**
     * 記錄首節點
     */
    private Node first;

    /**
     * 記錄前一個節點
     */
    private Node pre;

    public static void main(String[] args) {
        JosephTest josephTest = new JosephTest();
        josephTest.joseph(josephTest);
    }

    public void joseph(JosephTest josephTest) {

        josephTest.createCircleList(41);
        Node node = josephTest.first;// 當前節點,初始爲首節點
        Node next = null;// 當前節點的下一節點
        Node before = null;// 當前節點的上一節點

        int count = 1;// 初始爲1,因爲上面已經node賦值爲first了
        /**
         * 當全部kill掉所有報數=3的人後,僅剩2個元素的時候走進count==3中
         * node.next = next.next = node 如此結束循環
         */
        while (node != node.getNext()) {
            if (count == 3) {

                /**
                 * node節點置爲上一節點,並將上一節點的下節點置爲next(也就是死掉節點)的下節點
                 */
                node = before;
                node.setNext(next.getNext());
                count = 0;
            } else {
                /**
                 * 1.before暫存當前節點
                 * 2.next存儲當前節點的下一節點
                 * 3.當前節點置爲next成爲下一循環的當前節點
                 * 4.count+1
                 */
                before = node;
                next = node.getNext();
                node = next;
                count++;

            }

        }

        System.out.println(node.getItem());
        System.out.println(node.getNext().getItem());
        System.out.println(next.getItem());
    }

    @Test
    public void testCircleList() {
        JosephTest josephTest = new JosephTest();
        josephTest.createCircleList(8);
        Node node = josephTest.first;
        Node next = null;
        for (int i = 0; i < 43; i++) {
            next = node.getNext();
            node = next;
            if (next != null) {
                System.out.println(next.getItem());
            }

        }
    }

	// 創建循環鏈表
    public void createCircleList(int n) {
        for (int i = 1; i <= n; i++) {
            // 首節點
            if (i == 1) {
                first = new Node(i, null);
                pre = first;
                continue;
            }
            // 尾節點的下一個節點指向首節點即可構成循環鏈表
            if (i == n) {
                Node tail = new Node(n, first);
                pre.setNext(tail);
                continue;
            }

            Node newNode = new Node(i, null);
            pre.setNext(newNode);
            pre = newNode;
        }
    }

}

public class Node<T> {
    /**
     * 下一個節點
     */
    private Node next;

    /**
     * 數據
     */
    private T item;

    public Node(T item, Node next) {
        this.item = item;
        this.next = next;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public T getItem() {
        return item;
    }

    public void setItem(T item) {
        this.item = item;
    }

}

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