Loading

约瑟夫环(单向循环链表)

链表节点

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);
    }
}

结果:

image

posted @ 2022-05-27 11:31  liqiju  阅读(60)  评论(0编辑  收藏  举报