3,java数据结构和算法:约瑟夫环出队顺序, 单向环形链表的应用
什么是约瑟夫环? 就是数小孩游戏:


直接上代码: 要实现这个,只需要理清思路就好了
孩子节点:
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数据结构和算法:约瑟夫环出队顺序, 单向环形链表的应用的更多相关文章
- Java数据结构和算法(一)线性结构之单链表
Java数据结构和算法(一)线性结构之单链表 prev current next -------------- -------------- -------------- | value | next ...
- 《Java数据结构与算法》笔记-CH5-链表-3双端链表
/** * 双端链表的实现 */ class LinkA { public long dData; public LinkA next; public LinkA(long d) { dData = ...
- Java数据结构之单向环形链表(解决Josephu约瑟夫环问题)
1.Josephu(约瑟夫.约瑟夫环)问题: 设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m ...
- 循环列表的Java实现,解决约瑟夫环问题
import java.util.Scanner; /** * 循环列表的Java实现,解决约瑟夫环问题 * * @author LIU * */ public class LinkedList { ...
- 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现
本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是 ...
- Java数据结构和算法(六)——前缀、中缀、后缀表达式
前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...
- java数据结构与算法之栈(Stack)设计与实现
本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是一种用于 ...
- Java数据结构和算法 - 堆
堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...
- Java数据结构和算法 - 二叉树
前言 数据结构可划分为线性结构.树型结构和图型结构三大类.前面几篇讨论了数组.栈和队列.链表都是线性结构.树型结构中每个结点只允许有一个直接前驱结点,但允许有一个以上直接后驱结点.树型结构有树和二叉树 ...
随机推荐
- 『动善时』JMeter基础 — 7、jmeter.properties文件常用配置
目录 1.默认语言设置 2.配置默认编码格式 3.GUI图标放大比例设置 4.功能区工具栏图标大小设置 5.视图区目录树图标大小设置 6.内容区编辑字体设置 7.添加JMeter元素快捷键设置 8.捕 ...
- 使用C#实现一个PPT遥控器
说明 本项目参考了 https://github.com/yangzhongke/PhoneAsPrompter 项目来完成实现,并对其进行了一些修改完善. 完整代码可以到 https://githu ...
- 发布 .NET 5 带运行时单文件应用时优化文件体积的方法
自 .NET 发布起,.NET Framework 运行环境就是其摆脱不掉的桎梏.后来有了 .NET Core ,微软终于将自带运行时和单文件程序带给了我们.即便如此,大部分情况下开发者仍然不太满意: ...
- 缓冲流以及JAVA路径相关问题
缓冲流 缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO 次数,从而提高读写的效率. 字节缓冲流 按字节处理 字符缓冲流 按字符处理 实例练习:文 ...
- CRM系统有哪几种常见类型?
随着市场的快速变化,客户开始变得越来越重要,因此CRM客户管理系统开始逐渐被企业所认可.从CRM系统进入中国市场到现在十余年的发展中,越来越多的CRM厂商开始出现.为了满足不同行业.不同类型的企业的需 ...
- CSS3边界图片
目录 border-image border-image-slice border-image-width border-image-outset border-image-repeat border ...
- [bug] Maven [WARNING] 'parent.relativePath' of POM
参考 https://blog.csdn.net/simajinxiu/article/details/86667894
- 所有的 Unix Like 系统都会内建 vi 文书编辑器。vim 是vi的升级版本,它不仅兼容vi的所有指令 ,而且还有一些新的特性在里面。
所有的 Unix Like 系统都会内建 vi 文书编辑器.vim 是vi的升级版本,它不仅兼容vi的所有指令 ,而且还有一些新的特性在里面. https://blog.csdn.net/carolz ...
- C++课程设计 通讯录管理系统 原码及解析
设计题目:通信录管理系统 用C++设计出模拟手机通信录管理系统,实现对手机中的通信录进行管理. (一)功能要求 查看功能:选择此功能时,列出下列三类选择. A 办公类B 个人类C 商务类,当选中某类时 ...
- JQuery Ajax 请求参数 List 集合处理
引言 JQuery Ajax 发送请求参数一般都是基本类型,比如 String.int:那么,请求参数如果是 List 集合应该如何处理呢? 情况一:Aajx 发送 List 类型请求参数 举例如下: ...