Java中使用链表解决约瑟夫问题(丢手绢问题)
文章目录
- 文章目录
- 前言
- 一、思路分析
- 二、代码实现
- 1.Chird类建立
- 2.链表创建
- 3.功能实现
- 总结
其他解决方式:
Java中使用list解决约瑟夫问题https://blog.csdn.net/qq_35813811/article/details/127161381
前言
众所周知,约瑟夫问题又名丢手绢问题,是一个经典的算法问题。这里就以丢手绢问题来模拟约瑟夫问题的大致内容。问题的大致内容是:已知n个小孩(以编号1,2,3.....,n)围成一个圈。从编号为k的人开始报数,数到m的那个人出列,出列之后,剩下的人又继续报数,同时他的下一个人又从1开始报数,数到m的那个人又出列,剩下的人又继续报数。以此规律重复下去,直到小孩全部出列。
如图,这里以6个小孩作为例子说明问题:这里有6个小孩围成一个圈
当k=1,m=3时,表示从第一个小孩开始报数,数到第三个小孩时,小孩出列。
当第三个小孩出列之后,队伍中只剩下5个小孩,同时,此时从4号小孩开始报数,数到3时,第6个孩子出列。
六号孩子出列之后,场上仅剩下1,2,4,5号小孩,他们四个小孩也进行同样的操作。
以此类推,当最后一个小孩出列时,游戏结束。
一、思路分析
在本篇文章中,我们将使用Java语言中的链表来解决约瑟夫问题(丢手绢问题)。
由上述所知,该文章一共有n个小孩,从第k个小孩开始报数,报到第m个小孩时小孩出列,剩下的小孩接着报数。在上方的图解中,我们可以清晰的看出,这些小孩围在一起形成了一个环,当数到第n个小孩时,该环又重新轮回到第1个小孩处,继续报数。在这里,我们可以制作一个环形链表来解决这个问题。我们把这个环叫做约瑟夫环,以下是实现的图解:
在这里,我们可以利用两个中间变量来进行问题的解决。其中,i变量是从1开始,表示当前报数报的是多少,all则表示当前已经出列了多少个小孩,如果小孩都出列完成,则程序运行结束。
在这里,我们使用chird来代表小孩,当开始数数时,从第k个小孩开始数,这里就是从第1个小孩开始,当1号小孩报数之后,由2号小孩进行报数,此时2号小孩报2,则中间变量i就等于2。
当报到第三个小孩时,3号小孩报3,此时与m相同,则3号小孩出列,当循环到4号小孩时,i又等于1,重新在环中继续报数
在这个过程中,chird代表当前正在报数的小孩。但是在实际编写环形链表的过程中,会出现一个“头小孩”的问题,我们要将报第一个数的小孩当做头小孩,以这一个小孩为基准,利用i这个中间变量来获取第i个小孩,从而解决问题。当i=m时,第i个小孩出列,此时将出列之后的下一个小孩重新当做“头小孩”,以此来进行环形链表的获取。
二、代码实现
1.Chird类的实现
为模拟小孩,在该类中我们重新创建了一个新类Chird来表示小孩,该小孩拥有id,以及下一个小孩的属性next,拥有一个构造函数来new一个小孩,拥有一个toString方法来对小孩信息进行打印,代码如下:
class Chird {int id;Chird next;public Chird(int id) {this.id = id;}@Overridepublic String toString() {return "小孩id = "+this.id;}
}
2.链表的创建
在该类中,我们创建了一个单向链表新类,名为ChirdLinkedList,在这个类中,我们首先要定义一个“虚拟的头小孩”(头指针),有了这个“虚拟的头小孩”(头指针)之后,我们才可获取到第一个小孩。同时,我们在链表中实现了将单向链表转换为环形链表,已经链表的增删查功能。代码如下:
class ChirdLinkedList {Chird head = new Chird(0);//将链表更改为环形链表public void toCircularLinked() {Chird temp = head;if (temp.next == null) {return;}while (true) {if (temp.next == null) {temp.next = head.next;break;}temp = temp.next;}}// 更改头小孩public void changeHeadNext(Chird chird) {head.next = chird;}// 获取第i个小孩(相对于头小孩)public Chird getChird(int num) {if (num < 1) {return null;}int i = 0;Chird temp = head.next;while (temp != null) {i++;if (i == num) {return temp;}temp = temp.next;}return null;}//新增小孩public void addChird(int num) {Chird temp = head;while (true) {if (temp.next == null) {for (int i = 1; i <= num; i++) {Chird chird = new Chird(i);temp.next = chird;temp = temp.next;}break;}else {temp = temp.next;}}}//删除小孩public void deleteChird(int num) {if (num < 1) {return;}int i = 0;Chird temp = head;while (temp.next != null) {i++;if (i == num) {if (temp.next == head.next) {head.next = temp.next.next;}temp.next = temp.next.next;return;}temp = temp.next;}return;}
}
3.功能的实现
在实现了小孩和链表之后,我们就可以利用此对功能进行实现了。
public static void main(String[] args) {solveJosephQuestion(6,2,3);}public static void solveJosephQuestion(int n, int k , int m) {ChirdLinkedList chirdLinkedList = new ChirdLinkedList();chirdLinkedList.addChird(n);chirdLinkedList.toCircularLinked();Chird chird = chirdLinkedList.getChird(k);//更改第k个小孩为头小孩chirdLinkedList.changeHeadNext(chird);int i = 1;int all = 0;while (true) {if (i == m) {//输出出列的小孩名称System.out.println(chird.toString());all ++;//删除小孩并更改头小孩Chird chird2 = chirdLinkedList.getChird(m+1);chirdLinkedList.deleteChird(m);chirdLinkedList.changeHeadNext(chird2);//i归零i=0;//如果小孩总数等于出列小孩总数则退出循环if (n==all) {return;}} else {//i累加i++;chird = chirdLinkedList.getChird(i);}}}
总结
以上就是利用环形链表实现约瑟夫问题(丢手绢问题)的过程,在这个过程中主要创建了小孩类和链表类,分别实现了不同的功能,最后在函数中解决了约瑟夫问题(丢手绢问题),在实际编程的过程中还是要非常注意逻辑关系和编写顺序,如果中间的一些关键步骤顺序错了也会导致最后的结果错误喔~
Java中使用链表解决约瑟夫问题(丢手绢问题)相关推荐
- Java中使用list解决约瑟夫问题(丢手绢问题)
文章目录 文章目录 前言 一.思路分析 二.代码实现 总结 其他解决方式: Java中使用环形链表解决约瑟夫问题https://blog.csdn.net/qq_35813811/article/de ...
- java实现环形链表解决约瑟夫环问题
什么是环形链表? 环形链表就是单向链表的基础上让链表的首尾相连,形成一个环,这就是一个循环链表. 什么是约瑟夫环问题? 约瑟夫环如下: 约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数, ...
- 【Java】单循环链表解决约瑟夫环问题
问题描述 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自 ...
- java模拟单链表环形链表解决约瑟夫问题
java模拟环形链表解决约瑟夫问题 此文是观看尚硅谷韩老师的数据结构与算法学习视频整理的笔记 约瑟夫问题描述 约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算 ...
- 【数据结构作业—01】用单循环链表解决约瑟夫问题
实验作业一:线性表(链表) 1. 用单循环链表解决约瑟夫问题. 问题描述: 一个旅行社要从n个旅客中选出一名旅客,为他提供免费的环球旅行服务.旅行社安排这些旅客围成一个圆圈,从帽子中取出一张纸条,用上 ...
- php url乱码java接收,java中url乱码解决方法
java中url乱码解决方法:(推荐:java视频教程) 1.将字符串转码:newString("xxxxx".getBytes("iso-8859-1"),& ...
- (数据结构与算法)单向环形链表解决约瑟夫问题
约瑟夫(Josephu)问题 Josephu问题为: 设编号为1, 2,- n的n个人围坐一圈,约定编号为k (1<=k<=n) 的人从1开始报数,数到m的那个人出列,它的下一位又从1开始 ...
- 活用内核链表解决约瑟夫斯问题
约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为"约瑟夫环",也有的地方叫做"丢手绢". 问题 ...
- 用java解决约瑟夫循环问题,Java实现循环列表解决约瑟夫环问题
约瑟夫环:共有n个人围成一圈,从1开始报数,数到m的人出圈,求最后幸运者序号?? 下面用Java实现循环列表解决这个问题: package com.iteye.ljmdbc7a; import jav ...
最新文章
- Excel VBA开发中数字签名的管理
- DOM 之通俗易懂讲解
- ajax跨域请求.json文件,使用JSONP对JSON文件进行跨域Ajax请求
- Redis分布式缓存
- 使用doxygen和latex生成PDF文件
- 如何验证某个 string 是否为合法的 GUID ?
- vue-router配置介绍和使用方法(一)
- Android视频录制从不入门到入门系列教程(一)————简介
- linux下截图软件 shutter
- stm32的rxcallback再debug界面显示没有编译,uC/OS-III
- a4b5笔记本大小对比_【玩码】全新升级MX350独显 小米笔记本Pro 15 2020款为创造力而生...
- 全新外卖侠cps5.6全套微信小程序源码下载(内附加2.7.5版本微擎)
- 视频教程-Dubbo视频教程-Java
- C#海康摄像机SDK二次开发
- Python实例29:利用python自动创建多个Excel表格
- 成功的条件:高人指点、贵人相助、小人监督、个人奋斗
- 闭关六个月整理出来的微机原理知识点(特别适用河北专接本)
- 2019-11-12
- java毕业设计软件工程专业教辅平台课程子系统mybatis+源码+调试部署+系统+数据库+lw
- 移动端适配时对meta name=“viewport“ content=“width=device-width,initial-scale=1.0“的理解