文章目录

  • 文章目录
  • 前言
  • 一、思路分析
  • 二、代码实现
    • 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中使用链表解决约瑟夫问题(丢手绢问题)相关推荐

  1. Java中使用list解决约瑟夫问题(丢手绢问题)

    文章目录 文章目录 前言 一.思路分析 二.代码实现 总结 其他解决方式: Java中使用环形链表解决约瑟夫问题https://blog.csdn.net/qq_35813811/article/de ...

  2. java实现环形链表解决约瑟夫环问题

    什么是环形链表? 环形链表就是单向链表的基础上让链表的首尾相连,形成一个环,这就是一个循环链表. 什么是约瑟夫环问题? 约瑟夫环如下: 约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数, ...

  3. 【Java】单循环链表解决约瑟夫环问题

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

  4. java模拟单链表环形链表解决约瑟夫问题

    java模拟环形链表解决约瑟夫问题 此文是观看尚硅谷韩老师的数据结构与算法学习视频整理的笔记 约瑟夫问题描述 约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算 ...

  5. 【数据结构作业—01】用单循环链表解决约瑟夫问题

    实验作业一:线性表(链表) 1. 用单循环链表解决约瑟夫问题. 问题描述: 一个旅行社要从n个旅客中选出一名旅客,为他提供免费的环球旅行服务.旅行社安排这些旅客围成一个圆圈,从帽子中取出一张纸条,用上 ...

  6. php url乱码java接收,java中url乱码解决方法

    java中url乱码解决方法:(推荐:java视频教程) 1.将字符串转码:newString("xxxxx".getBytes("iso-8859-1"),& ...

  7. (数据结构与算法)单向环形链表解决约瑟夫问题

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

  8. 活用内核链表解决约瑟夫斯问题

    约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为"约瑟夫环",也有的地方叫做"丢手绢". 问题 ...

  9. 用java解决约瑟夫循环问题,Java实现循环列表解决约瑟夫环问题

    约瑟夫环:共有n个人围成一圈,从1开始报数,数到m的人出圈,求最后幸运者序号?? 下面用Java实现循环列表解决这个问题: package com.iteye.ljmdbc7a; import jav ...

最新文章

  1. Excel VBA开发中数字签名的管理
  2. DOM 之通俗易懂讲解
  3. ajax跨域请求.json文件,使用JSONP对JSON文件进行跨域Ajax请求
  4. Redis分布式缓存
  5. 使用doxygen和latex生成PDF文件
  6. 如何验证某个 string 是否为合法的 GUID ?
  7. vue-router配置介绍和使用方法(一)
  8. Android视频录制从不入门到入门系列教程(一)————简介
  9. linux下截图软件 shutter
  10. stm32的rxcallback再debug界面显示没有编译,uC/OS-III
  11. a4b5笔记本大小对比_【玩码】全新升级MX350独显 小米笔记本Pro 15 2020款为创造力而生...
  12. 全新外卖侠cps5.6全套微信小程序源码下载(内附加2.7.5版本微擎)
  13. 视频教程-Dubbo视频教程-Java
  14. C#海康摄像机SDK二次开发
  15. Python实例29:利用python自动创建多个Excel表格
  16. 成功的条件:高人指点、贵人相助、小人监督、个人奋斗
  17. 闭关六个月整理出来的微机原理知识点(特别适用河北专接本)
  18. 2019-11-12
  19. java毕业设计软件工程专业教辅平台课程子系统mybatis+源码+调试部署+系统+数据库+lw
  20. 移动端适配时对meta name=“viewport“ content=“width=device-width,initial-scale=1.0“的理解

热门文章

  1. 使用mac电脑预览功能修改图片尺寸以及裁剪
  2. 玩赚游戏中的数字经济未来以及元宇宙空间
  3. Word2000 的命令ID,识货的进
  4. vue3项目目录结构
  5. Python依赖库、安装包(源码安装)
  6. [译]Core Animation 3D介绍(第2部分)
  7. Intel MPK介绍
  8. 如何创建网站?企业如何创建网站?
  9. MySQL建库建表索引规范
  10. 解析网页(html和json)