Loading

环形链表解决约瑟夫问题

约瑟夫问题

 据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
 N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。

构思

我们可以采用环形链表解决约瑟夫问题。
环形链表构建思路:

约瑟夫问题实现思路:

代码实现

  1. 节点类
package com.linkedlist.circlesinglelinkedlist;

public class Node {
    private int no;
    private Node next;

    public Node() {
    }

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

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Node getNext() {
        return next;
    }

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

  1. 环形链表类
package com.linkedlist.circlesinglelinkedlist;

public class CircleSingleLinkedList {
    private Node first = null;
    public void addNode(int num){
        if(num < 1){
            System.out.println("添加节点数不能小于1!");
        }
        Node cur = null;
        for (int i = 1; i <= num; i++) {
            Node node = new Node(i);
            if(i == 1){
                first = node;
                first.setNext(first);
                cur = first;
            }else{
                cur.setNext(node);
                node.setNext(first);
                cur = cur.getNext();
            }
        }
    }
    public void list(){
        if(first == null){
            System.out.println("环形链表为null!");
            return;
        }
        Node cur = first;
        while(cur.getNext() != first){
            System.out.println("编号:"+cur.getNo());
            cur = cur.getNext();
        }
        System.out.println("编号:"+cur.getNo());
    }
    public void Josephus(int begin,int count,int num){
        if(begin < 1 || count < 0 || begin > num){
            System.out.println("参数不正确,请重新输入!");
            return;
        }
        Node helper = first;
        //让helper指向最后节点
        while(helper.getNext() != first){
            helper = helper.getNext();
        }
        //让helper和first遍历begin - 1
        for (int i = 0; i < begin - 1; i++) {
            helper = helper.getNext();
            first = first.getNext();
        }
        //进行报数
        while(true){
            //只剩下一个节点
            if(helper == first){
                break;
            }
            for (int i = 0; i < count - 1; i++) {
                helper = helper.getNext();
                first = first.getNext();
            }
            System.out.println("编号:"+first.getNo()+"出圈!");
            first = first.getNext();
            helper.setNext(first);
        }
        System.out.println("存活编号:"+first.getNo());
    }
}

posted @ 2021-11-09 16:35  IamHzc  阅读(44)  评论(0编辑  收藏  举报