1. 程式人生 > 其它 >約瑟夫環(單向迴圈連結串列)

約瑟夫環(單向迴圈連結串列)

連結串列節點

public class Node {
    int data;
    Node next;

    public Node(int data) {
        this.data = data;
    }
}

構造單向迴圈連結串列

/**
 * 單向迴圈連結串列
 */
public class SingleLoopLink {
    private Node head; // 引用頭節點
    private Node last; // 引用最後一個節點

    // 末尾插入一個元素,單元素插入
    private boolean add(int e) {
        Node node = new Node(e);
        if (head == null) {
            head = node;
            head.next = head;
            last = head;
            return true;
        }
        node.next = last.next;
        last.next = node;
        last = node;    // last指向最後一個節點
        return true;
    }

    // 返回頭節點
    public Node getHead() {
        return head;
    }

    // 列印單向迴圈連結串列
    public String print() {
        if (head == null) return "[]";
        Node p = head;
        StringBuilder sb = new StringBuilder();
        while (p.next != head) {
            sb.append(p.data + ", ");
            p = p.next;
        }
        sb.append(p.data);
        return "[" + sb.toString() + "]";
    }

    /**
     * 單向迴圈連結串列解決約瑟夫環問題
     * 假設有11(1-11)個小孩,數到7的小孩離開,那麼勝利者是哪個小孩呢?出圈的順序又是多少?
     * 共有 n=11人, 喊到m=7 出列。
     * 出圈的順序為:7  3  11  9  8  10  2  6  1  4  5
     */
    public void round(int n, int m) {
        if (n < m) {
            System.out.println("n不能小於m");
            return;
        }
        for (int i = 0; i < n; i++) {
            add(i + 1);
        }
        System.out.println("連結串列中的元素:" + print());
        // 計數器 到7出列,從1開始
        int count = 1;
        while (head.next.data != head.data) {
            // 如果count=7,刪除當前節點,重置count=1
            if (count == m) {
                System.out.println("離開:" + head.data);
                head.data = head.next.data;
                head.next = head.next.next;
                count = 1;
                continue;
            }
            count++;
            head = head.next;
        }
        System.out.println("勝利者:" + head.data);
    }
}

測試

public class AppTest {
    public static void main(String[] args) {
        SingleLoopLink link = new SingleLoopLink();
        link.round(11, 7);
    }
}

結果: