什么是约瑟夫环? 就是数小孩游戏:



直接上代码: 要实现这个,只需要理清思路就好了

孩子节点:

class Boy{
int no;//当前孩子的编码
Boy next; // 下一节点 public Boy(int no) {
this.no = no;
} public Boy(int no, Boy next) {
this.no = no;
this.next = next;
} @Override
public String toString() {
return "Boy{" +
"no=" + no +
'}';
}
}

单向环形链表:

 //约瑟夫环, 单向环状链表
class SingleCircleLinkList{
//1,先造一个first指针,为null, 用来指向第一个小孩, 永远不会变
//2, 创建一个 curBoy指针,当只有一个小孩时候,curBoy指向第一个小孩,
// 当有n个小孩时, curBoy永远指向当前的小孩, 这样的好处是便于遍历
Boy first = null;
int boyCount; /**
* 根据 n 个数创建 约瑟夫环
* @param n
*/
public void creatYosepfuCircle(int n){
//思路: 1,创建一个first指针, 用来指向第一个节点,永远不会变
// 2, 创建一个curBoy指针, 用来指向当前节点, 当只有一个节点时,first 和curBoy都指向这个节点,
// 当有多个节点时候, first指向第一个节点, curBoy指向最后一个节点, 用来遍历使用? Boy curBoy = null;//curBoy指针,用来指向当前节点,
if (n < 1) {
System.out.println("孩子节点不能小于1");
return;
}
this.boyCount = n;
for (int i = 1; i <=n; i++) {
//根据n 创建孩子节点
Boy boy = new Boy(i);
if(i == 1){
first = boy;//first指针指向第一个节点
first.next = first;//指向自己
curBoy = first;//当前指针指向第一个节点
}else{
curBoy.next = boy;//指定当前节点的下一节点
boy.next = first;//指向first指针
curBoy = boy;//移动curBoy指针,指向当前节点
}
}
} //遍历约瑟夫环
public void show(){
if(first == null){
System.out.println("没有小孩节点");
return;
}
//使用第三方变量 temp 遍历
Boy temp = first;
while (true) {
System.out.println("孩子节点是:"+temp.no);
if(first == temp.next){//当前节点的下一节点 == first 说明到尾部了
//遍历完毕
break;
}
temp = temp.next;
}
} //约瑟夫环 出环序列:
/**
* 游戏规则:
* 1-2-3-4-5的环形对列,
* (1-2-3-4-5)从1 开始数3个数, 3出队,
* (1-2-4-5),从4开始数3个数, 1出队.
* (2-4-5),从2开始数3个数, 5出队,
* (2-4) 从2开始数3个数, 2出队,
* (4) 4出队
*
* beginNum: 表示从第几个小孩开始数数
* countNum: 表示数几个下
*/
public void popBoy(int beginNum,int countNum){
//思路: 1, 定义二个指针, first指针已经指向了第一个节点, helper指针先指向环形链表的最后一个节点
// 2, 开始数数之前, 先将这二个指针,向后移动 beginNum-1次. 即从第3个小孩开始数数, 需要先将指针移动到这里
// 3, 循环数数, 找到要出队的那个节点,怎么找到? 就是将这二个指针, 向后移动 countNum-1次, first指针指的节点就是要出队的节点
// 即 数数countNum-1 后,该节点出队
// 4, 将该节点出队, 并将first指针指向下一节点, helper指针指向first指针
// 5, 循环结束后, 说明只剩一个节点了,该节点出队 if(this.first == null ||beginNum < 1 || beginNum > this.boyCount){
System.out.println("从第几个小孩开始,beginNum不能为0,不能大于环形单向链表的长度: " + this.boyCount);
}
//1, 定义二个指针, first指针已经指向了第一个节点, helper指针先指向环形链表的最后一个节点
Boy helper = first;
while(true){
if (helper.next == first) {
break;//说明到helper指针已经 到链表最后节点
}
helper = helper.next;
} //2, 开始数数之前, 先将这二个指针,向后移动 beginNum-1次. 即从第3个小孩开始数数, 需要先将指针移动到这里
for (int i = 0; i < beginNum - 1; i++) {
first = first.next;
helper = helper.next;
}
//3, 循环数数, 找到要出队的那个节点,怎么找到? 就是将这二个指针, 向后移动 countNum-1次, first指针指的节点就是要出队的节点
// 即 数数countNum-1 后,该节点出队
while (true) {
if (helper == first) {
break;//此时说明, 只有一个节点了
}
//开始数数,就是将 这二个指针 都向后移动countNum-1 次
for (int i = 0; i < countNum - 1; i++) {
first = first.next;
helper = helper.next;
}
//此时first指针指的就是 要出队的节点
System.out.printf("小孩%d出队\n",first.no);
//4, 将该节点出队, 并将first指针指向下一节点, helper指针指向first指针
first = first.next;
helper.next = first; }
//5, 循环结束后, 说明只剩一个节点了,该节点出队
System.out.printf("小孩%d出队\n",first.no);
} }

测试结果:

    public static void main(String[] args){
//创建约瑟夫环
SingleCircleLinkList singleCircleLinkList = new SingleCircleLinkList();
singleCircleLinkList.creatYosepfuCircle(5);
singleCircleLinkList.show();
System.out.println("----------");
//约瑟夫 出队
singleCircleLinkList.popBoy(1,3);// 3-1-5-2-4
}

3,java数据结构和算法:约瑟夫环出队顺序, 单向环形链表的应用的更多相关文章

  1. Java数据结构和算法(一)线性结构之单链表

    Java数据结构和算法(一)线性结构之单链表 prev current next -------------- -------------- -------------- | value | next ...

  2. 《Java数据结构与算法》笔记-CH5-链表-3双端链表

    /** * 双端链表的实现 */ class LinkA { public long dData; public LinkA next; public LinkA(long d) { dData = ...

  3. Java数据结构之单向环形链表(解决Josephu约瑟夫环问题)

    1.Josephu(约瑟夫.约瑟夫环)问题: 设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m ...

  4. 循环列表的Java实现,解决约瑟夫环问题

    import java.util.Scanner; /** * 循环列表的Java实现,解决约瑟夫环问题 * * @author LIU * */ public class LinkedList { ...

  5. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  6. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  7. java数据结构与算法之栈(Stack)设计与实现

    本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是一种用于 ...

  8. Java数据结构和算法 - 堆

    堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...

  9. Java数据结构和算法 - 二叉树

    前言 数据结构可划分为线性结构.树型结构和图型结构三大类.前面几篇讨论了数组.栈和队列.链表都是线性结构.树型结构中每个结点只允许有一个直接前驱结点,但允许有一个以上直接后驱结点.树型结构有树和二叉树 ...

随机推荐

  1. poj1190深搜 生日蛋糕

    题意:      让你制作一个蛋糕,这个蛋糕有m层,而且每层都是圆柱形,并且每一层都必须满足 ri>ri+1 && hi > hi+1,然后给出蛋糕的总体积是n*PI,还有 ...

  2. Linux中的.bash_ 文件详解

    目录 .bash_history .bash_logout .bash_profile .bashrc 每个用户的根目录下都有四个这样的 bash文件,他们是隐藏文件,需要使用-a参数才会显示出来 . ...

  3. 【python】Leetcode每日一题-森林中的兔子

    [python]Leetcode每日一题-森林中的兔子 [题目描述] 森林中,每个兔子都有颜色.其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色.我们将这些回答放在 answers ...

  4. linux中定时运行php(每分钟执行一次为例)

    注:使用Crontab定时执行php脚本文件 1. 安装crontab yum install crontabs 说明:/sbin/service crond start //启动服务/sbin/se ...

  5. IIS部署.Net5全流程

    介绍 Internet Information Services (IIS) 是一种灵活.安全且可管理的 Web 服务器,用于托管 Web 应用(包括 ASP.NET Core).虽然我们的程序可以跨 ...

  6. 个人项目作业$\cdot$求交点个数

    个人项目作业\(\cdot\)求交点个数 一.作业要求简介 本次作业是北航计算机学院软件工程课程的个人项目作业,个人开发能力对于软件开发团队是至关重要的,本项目旨在通过一个求几何图形的交点的需求来使学 ...

  7. BUAA-OO-第三单元总结

    面向对象第三单元JML总结 JML理论基础及工具链梳理 JML语言理论基础 JML语言是对于JAVA进行规格化设计的一种表述语言,他能以一种统一化语言,逻辑性强的格式,向程序设计者描述这一方法实现的功 ...

  8. Go 函数详解

    一.函数基础 函数由函数声明关键字 func.函数名.参数列表.返回列表.函数体组成 函数是一种类型.函数类型变量可以像其他类型变量一样使用,可以作为其他函数的参数或返回值,也可以直接调用执行 函数名 ...

  9. 17.继承 and18.接口和多态 内部类 匿名内部类,Lambda表达式

    1. 继承 1.1 继承的实现(掌握) 继承的概念 继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法 实现继承的格式 继承通过extends实现 ...

  10. Linux(深度)系统安装富士施乐(网络)打印机

    一般来讲,linux系统识别打印机没有问题,重点难点在于后面设置.此文特别感谢:河北石龙的陈一繁销售代表.P288dw施乐官网并未提供Linux的驱动并在安装过程中遇到很多问题,其不厌其烦的为我联系厂 ...