栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java数据结构与算法--Josephus(约瑟夫、约瑟夫环) 问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java数据结构与算法--Josephus(约瑟夫、约瑟夫环) 问题

1. 单向环形链表应用场景

Josephu(约瑟夫、约瑟夫环) 问题

  • Josephu 问题为:设编号为 1,2,… n 的 n 个人围坐一圈,约定编号为 k(1<=k<=n)的人从 1 开始报数,数到 m 的那个人出列,它的下一位又从 1 开始报数,数到 m 的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
  • 提示:用一个不带头结点的循环链表来处理 Josephu 问题:先构成一个有 n 个结点的单循环链表,然后由 k 结点起从 1 开始计数,计到 m 时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从 1 开始计数,直到最后一个结点从链表中删除算法结束。
2. 单向环形链表介绍

3. Josephu 问题

1) 约瑟夫问题的示意图


2) 约瑟夫问题-创建环形链表的思路图解


3) 约瑟夫问题-小孩出圈的思路分析图


4) Josephu 问题的代码实现

public class Josepfu {
    public static void main(String[] args) {
        CircleSinglelinkedList circleSinglelinkedList = new CircleSinglelinkedList(20);
        // circleSinglelinkedList.showBoy();
        circleSinglelinkedList.countBoy(1,2);
    }
}
class CircleSinglelinkedList{
    private Integer linkedListLength;
    private Boy first = null;

    public Integer getlinkedListLength() {
        return this.linkedListLength;
    }

    public void setlinkedListLength(Integer linkedListLength) {
        this.linkedListLength = linkedListLength;
    }

    public CircleSinglelinkedList(Integer linkedListLength) {
        this.linkedListLength = linkedListLength;
        this.addBoy(linkedListLength);
    }

    private void addBoy(int nums) {
        if (nums<1){
            System.out.println("人数不能小于1");
            return;
        }

        Boy curBoy = null;
        for (int i = 1; i <= nums; i++) {
            Boy boy = new Boy(i);
            if (i==1){
                this.first = boy;
                first.setNext(first);
                curBoy = first;
            }else {
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }
    }

    public void showBoy(){
        if (this.first==null){
            System.out.println("链表为null");
            return;
        }

        Boy curBoy = this.first;
        while (true){
            System.out.println("小孩编号:"+curBoy.getNo());
            if (curBoy.getNext()==this.first){
                break;
            }
            curBoy = curBoy.getNext();
        }
    }
    
    public void countBoy(int startNo,int countNum){
        if (this.first ==null || startNo < 1 || startNo>this.linkedListLength){
            System.out.println("输入的数据有误");
            return;
        }
        // 创建辅助对象
        Boy helper = this.first;

        // 让helper处于first后一个对象
        while (true){
            if (helper.getNext()==this.first){
                break;
            }
            helper = helper.getNext();
        }

        // 让first移动到startNo处,移动startNo-1次
        for (int i = 0; i < startNo - 1; i++) {
            this.first = this.first.getNext();
            helper = helper.getNext();
        }

        // 开始数数出圈
        while (true){
            if (helper == this.first){
                // 表示圈内只剩一个小孩
                break;
            }
            // helper 和first 同时移动countNum-1次
            for (int i = 0; i < countNum - 1; i++) {
                this.first = first.getNext();
                helper = helper.getNext();
            }
            System.out.println("要出圈的小孩为:"+ first.getNo());
            this.first = this.first.getNext();
            helper.setNext(this.first);
        }
        // 圈内只剩一个小孩
        System.out.println("圈内最后一个小孩为:"+this.first.getNo());

    }
}
class Boy{
    private Integer no;
    private Boy next;

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

    public Integer getNo() {
        return no;
    }

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

    public Boy getNext() {
        return next;
    }

    public void setNext(Boy next) {
        this.next = next;
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/294382.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号