约瑟夫问题(Java)数据结构---环形链表

约瑟夫问题(Java)数据结构—环形链表

博客说明

文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!

说明

约瑟夫(Josephus)问题是单向环形链表的一种体现,也就是丢手帕问题。

一般形式

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。

分析:

(1)由于对于每个人只有死和活两种状态,因此可以用布尔型数组标记每个人的状态,可用true表示死,false表示活。

(2)开始时每个人都是活的,所以数组初值全部赋为false。

(3)模拟杀人过程,直到所有人都被杀死为止。

代码

package link;

public class Josephus {
    public static void main(String[] args) {
        CircleSingleLinkList circleSingleLinkList = new CircleSingleLinkList();
        circleSingleLinkList.addBoy(6);
        //circleSingleLinkList.list();
        circleSingleLinkList.out(1,5,6);
    }
}


//创建环形的单向链表
class CircleSingleLinkList{
    //创建一个first节点,没有编号
    private Boy first = new Boy(-1);
    //添加小孩节点
    public void addBoy(int nums){
        if (nums < 1){
            System.out.println("nums不正确");
            return;
        }
        Boy temp = null;//辅助指针
        for (int i = 1; i <= nums; i++) {
            Boy boy = new Boy(i);
            if (i == 1){
                first = boy;
                first.setNext(first);
                temp = first;
            }else {
                temp.setNext(boy);
                boy.setNext(first);
                temp = boy;
            }
        }
    }

    //遍历
    public void list(){
        if (first == null){
            System.out.println("链表为空");
            return;
        }
        Boy temp = first;
        while (true){
            System.out.printf("小孩的编号%d\n",temp.getNo());
            if (temp.getNext() == first){
                break;
            }
            temp = temp.getNext();
        }
    }

    //出圈顺序
    public void out(int start,int count,int nums){
        if (first == null || start < 1 || start > nums){
            System.out.println("输入的参数有问题");
            return;
        }
        Boy temp = first;
        while (true){
            if (temp.getNext() == first){
                break;
            }
            temp = temp.getNext();
        }
        for (int j = 0; j < start - 1; j++) {
            first = first.getNext();
            temp = temp.getNext();
        }
        //移动辅助指针
        while (true){
            if (temp == first){
                break;
            }
            for (int j = 0; j < count -1; j++) {
                first = first.getNext();
                temp = temp.getNext();
            }
            System.out.printf("出圈的%d\n",first.getNo());
            first = first.getNext();
            temp.setNext(first);
        }
        System.out.printf("最后的%d\n",first.getNo());
    }
}

//创建一个类,表示一个节点

class Boy{
    private int no;
    private Boy next;

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

    public int getNo() {
        return no;
    }

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

    public Boy getNext() {
        return next;
    }

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

菜鸟教程

万能的网络

以及勤劳的自己

发布了191 篇原创文章 · 获赞 513 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_45163122/article/details/105047062