关于单向循环链表的约瑟夫问题(Java实现)

最近在学习链表时,遇到单向循环链表中的约瑟夫问题。在构建循环链表的代码上,我有一点很不理解,遂记录下来。

Josephu问题为:

设编号为1, 2,.. n的n个人围坐- -圈,约定编号为k (1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一-位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

提示:用一个不带头结点的循环链表来处理Josephu问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。

构建一个单向的环形链表思路:
1.先创建第一个节点让first指向该节点,并形成环形
2.后面当我们每创建- -个新的节点,就把该节点,加入到已有的环形链表中即可.
遍历环形链表
1.先让一个辅助指针(变量)curBoy,指向frt节点
2.然后通过一-个while循环遍历该环形链表即可curBoy.next == first结束

代码清单:

package lianbiao;
public class Josepfu {
  public static void main(String[]args){
         CircleSingleLinkedList circleSingleLinkedList =new CircleSingleLinkedList();
         circleSingleLinkedList.addBoy(5);//加入5个小孩节点
         circleSingleLinkedList.showBoy();
         circleSingleLinkedList.countBoy(1, 2, 5);
         }
}
 //创建一个环形的单向链表
 class CircleSingleLinkedList{
     // 创建一个first节点当前没有编号
     private Boy first = null;
     //添加小孩节点,构建成一个环形的链表
     public void addBoy(int nums) {
 // nums做一个数据校验
         if (nums < 1) {
             System.out.println("nums的值不正确");
             return;
         }
             Boy curBoy = null; //辅助指针,帮助构建环形链表
 //使用for来创建我们的环形链表
             for (int i = 1; i <= nums; i++) {
 // 根据编号,创建小孩节点
                 Boy boy = new Boy(i);
 // 如果是第一个小孩
                 if (i == 1) {
                     first = boy;
                     first.setNext(first);//构成环
                     curBoy = first; //让curBoy指向第一个小孩
                 } else {
                     curBoy.setNext(boy);//
                     boy.setNext(first);//
                     curBoy = boy;
                 }
             }
         }
    
   //遍历当前的环形链表
     public void showBoy() {
     //判断链表是否为空
      if(first== null) {
       System.out.println("没有任何小孩~");
      return;
     }
     //因为first不能动,因此我们仍然使用一个辅助指针完成遍历
      Boy curBoy = first;
      while (true) {
       System.out.printf("小孩的编号%d \n", curBoy.getNo());
       if (curBoy.getNext()==first) {// 说明已经遍历完毕
        break;
      }
       curBoy = curBoy.getNext(); // curBoy后移
       }
      }
    
     public void countBoy(int startNo, int countNum, int nums) {
      //先对数据进行校验
      if (first== null || startNo< 1 || startNo> nums) {
       System.out. println("参数输入有误,请 重新输入");
       return;
      }
      //创建要给辅助指针,帮助完成小孩出圈
      Boy helper= first;
      //需求创建一个辅助指针(变量) helper ,事先应该指向环形链表的最后这个节点
      while (true) {
       if (helper.getNext()==first) { //说明helper 指向最后小孩节点
        break;
       }
       helper = helper.getNext();
      }
      //小孩报数前,先让first 和helper 移动k- 1次
      for(int j= 0;j < startNo- 1;j++) {
      first = first.getNext();
      helper = helper .getNext();
      }
      //当小孩报数时,让first 和helper 指针同时的移动m - 1次,然后出圈
      //这里是一个循环操作,知道圈中只有一个节点
      while(true) {
      if(helper == first) { //说明圈中只有一个节点
       break;
      }
       //让first 和helper 指针同时的移动countNum- 1
       for(int j = 0;j < countNum- 1;j++) {
        first = first. getNext();
        helper = helper.getNext();
       }
       //这时first 指向的节点,就是要出圈的小孩节点
       System.out.printf("小孩%d出圈\n", first.getNo());
       //这时将first指向的小孩节点出圈
       first = first.getNext();
       helper .setNext(first); //
       }
       System.out. printf("最后留在圈中的小孩编号%d \n", first. getNo());
       }
      }
  class Boy {
     //创建一个Boy类,表示-一个节点
     private int no;//编号
     private Boy next;//指向下一个节点,默认null
     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;
     }
  }
 问题描述:
在addboy()方法中
 
 

关于单向循环链表的约瑟夫问题(Java实现)的更多相关文章

  1. Java 用单向循环链表实现 约瑟夫问题

    public class lianbiao2 { class Node{ Node next; int number; public Node getNext() { return next; } p ...

  2. C语言单向循环链表解决约瑟夫问题

    据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,4 ...

  3. (java实现)单向循环链表

    什么是单向循环链表 单向循环链表基本与单向链表相同,唯一的区别就是单向循环链表的尾节点指向的不是null,而是头节点(注意:不是头指针). 因此,单向循环链表的任何节点的下一部分都不存在NULL值. ...

  4. 使用java的循环单向链表解决约瑟夫问题

    什么是约瑟夫问题 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定 ...

  5. JS数据结构第三篇---双向链表和循环链表之约瑟夫问题

    一.双向链表 在上文<JS数据结构第二篇---链表>中描述的是单向链表.单向链表是指每个节点都存有指向下一个节点的地址,双向链表则是在单向链表的基础上,给每个节点增加一个指向上一个节点的地 ...

  6. PTA 6-15 用单向循环链表实现猴子选大王 (20 分)

    一群猴子要选新猴王.新猴王的选择方法是:让n只候选猴子围成一圈,从某位置起顺序编号为1~n号.每只猴子预先设定一个数(或称定数),用最后一只猴子的定数d,从第一只猴子开始报数,报到d的猴子即退出圈子: ...

  7. Have Fun with Numbers及循环链表(约瑟夫问题)

    1. 循环链表(约瑟夫问题) https://github.com/BodhiXing/Data_Structure 2. Have Fun with Numbers https://pta.pate ...

  8. 基于visual Studio2013解决算法导论之021单向循环链表

     题目 单向循环链表的操作 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> ...

  9. Python 单向循环链表

    操作 is_empty() 判断链表是否为空 length() 返回链表的长度 travel() 遍历 add(item) 在头部添加一个节点 append(item) 在尾部添加一个节点 inser ...

随机推荐

  1. JZOJ 4611. 【NOI2016模拟7.11】接水问题 (贪心+A*+可持久化线段树)

    Description: https://gmoj.net/senior/#main/show/4611 题解: 先把A从大到小排序,最小的由排序不等式显然. 考虑类似第k短路的A*的做法. 定义状态 ...

  2. 透过面试题掌握Redis【持续更新中】

    本文已收录到1.1K Star的Github开源项目<面试指北>,想要了解更多内容,大家可以看一看这个项目,希望大家帮忙给一个star,谢谢了! <面试指北>项目地址:http ...

  3. 获取MP4媒体文件时长

    由于之前上传MP4文件没有保存视频时长,现在有需要,所以只好写代码读取时长.找了几个发现是 c/c++ 实现,或者是借助 FFmpeg 实现. 一个偶然在 GitHub 上面发现一个 c 文件,由于获 ...

  4. RESTful api 功能测试

    0 为什么要写测试代码 代码写好了,如果能点或者能看,开发人员一般会自己点点或看看,如果没有发现问题就提交测试:更进一步,代码写好后,运行测试代码,通过后提交测试.将流程抽象下: 功能1编码-> ...

  5. ActiveMQ 反序列化漏洞(CVE-2015-5254)复现

    1.运行漏洞环境 sudo docker-compose up -d 环境运行后,将监听61616和8161两个端口.其中61616是工作端口,消息在这个端口进行传递:8161是Web管理页面端口.访 ...

  6. [Python3]星号*的打开方式

    python中,* 号除了用来做数量乘法,还有其他的用处. 结论 概括的来说,就是对修饰的变量进行拆分, 对修饰的形式参数进行参数聚集. 单*号,将被修饰的变量按元素方式拆分, 对修饰的形式参数进行参 ...

  7. Java实现 LeetCode 781 森林中的兔子(分析题)

    781. 森林中的兔子 森林中,每个兔子都有颜色.其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色.我们将这些回答放在 answers 数组里. 返回森林中兔子的最少数量. 示例: ...

  8. Java实现 蓝桥杯 算法提高 歌唱比赛(暴力)

    试题 算法提高 歌唱比赛 问题描述 X市正在进行歌唱比赛,请你写一个程序计算得分. 每名选手从1到N编号,每名选手的综合成绩由以下几个部分组成: 1.歌唱得分占70% 2.才艺展示得分占20% 3.观 ...

  9. Java实现 蓝桥杯 算法训练 数字游戏

    试题 算法训练 数字游戏 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个1-N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列 ...

  10. Java实现第八届蓝桥杯外星日历

    外星日历 题目描述 某星系深处发现了文明遗迹. 他们的计数也是用十进制. 他们的文明也有日历.日历只有天数,没有年.月的概念. 有趣的是,他们也使用了类似"星期"的概念, 只不过他 ...