五、单向环形链表---实现约瑟夫(Josephu)问题
使用单向环形链表实现约瑟夫(Josephu)问题
1.约瑟夫(Josephu)问题描述
Josephu 问题为:设编号为 1,2,… n 的 n 个人围坐一圈,约定编号为 k(1<=k<=n)的人从 1 开始报数,数到 m 的那个人出列,它的下一位又从 1 开始报数,数到 m 的那个人又出列,依次类推,直到所有人出列为止,由此 产生一个出队编号的序列。
2.小提示
用一个不带头结点的循环链表来处理 Josephu 问题:先构成一个有 n 个结点的单循环链表,然后由 k 结点起从 1 开 始计数,计到 m 时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从 1 开始计数,直到最后一个结点从链表中删除算法结束。
3.约瑟夫(Josephu)问题—创建单向环形单链表的思路和图解
思路:
(1)先创建一个结点,让first指针指向该节点,并使first.next=first使得第一个结点自己 形成一个环,并将辅助指针指向该节点。核心代码是:
if(i==1){first=boy;//如果只有一个结点,就先自己构成一个环first.next=first;//让辅助指针curBoy指向第一个小孩curBoy=first;}
(2)后面没创建一个结点,就将该节点加入到该环形链表中,核心代码是
curBoy.next=boy;boy.next=first;curBoy=boy;
图解:
4.约瑟夫(Josephu)问题—遍历环形单链表思路
(1)创建一个辅助指针curBoy,指向first结点
(2)然后通过while循环遍历单向环形单链表,直到curBoy.next==first结束
5.约瑟夫(Josephu)问题核心—小孩子出圈顺序思路分析
(1)举例:根据用户的输入,生成一个小孩的顺序
n=5:表示单链表中有五个结点,即初始时圈中有五个小孩
k=1:表示从第一个孩子开始报数
m=2:每次数两个人,出圈一个孩子
(2)思路分析
—创建一个helper指针,起始时指向唤醒链表的最后一个结点。
—小孩报数前,先让first指针和helper指针同时移动k-1次(因为题目不一定是从第一个孩子开始报数)
—之后小孩报数时,将first指针和helper指针同时移动m-1次
----这时可以将first指向的小孩结点同时出圈:first=first.next helper.next=first;
(3)案例出圈顺序为:2–>4–>1–>5–>3
6.约瑟夫(Josephu)问题代码实现
package cn.zzw.algorithm.LinkedList;//使用单向环形链表实现约瑟夫问题
public class Josepfu {public static void main(String[] args) {//测试环形链表和遍历CircleSingleLinkedList circleSingleLinkedList=new CircleSingleLinkedList();circleSingleLinkedList.addBoy(5);circleSingleLinkedList.show();//测试小孩结点出圈顺序是否正确circleSingleLinkedList.countBoy(1,2,5);}
}//创建一个Boy类,表示一个环形链表中的一个结点
//当然可以把属性no和next设为私有,之后使用get和set方法进行访问
class Boy
{public int no;public Boy next;//表示结点的下一个结点,默认值为nullpublic Boy(int no) {this.no = no;}@Overridepublic String toString() {return "Boy{" +"no=" + no +'}';}
}//创建一个环形的单链表
class CircleSingleLinkedList
{//创建一个first结点,当前默认为null,没有后继结点private Boy first=null;//添加小孩结点,构建一个环形的链表public void addBoy(int nums){//为了防止nums不合法,对其进行数据校验if(nums<1){System.out.println("nums数据值不合法");return;}//使用辅助指针,帮助构建环形链表Boy curBoy=null;for(int i=1;i<=nums;i++){//根据编号,创建小孩结点Boy boy=new Boy(i);//如果小孩是第一个结点if(i==1){first=boy;//如果只有一个结点,就先自己构成一个环first.next=first;//让辅助指针curBoy指向第一个小孩curBoy=first;}else{curBoy.next=boy;boy.next=first;curBoy=boy;}}}//遍历当前链表public void show(){//判断当前链表是否为空if (first==null){System.out.println("当前链表为空,没有任何结点");return;}//first指针不能动,应该使用一个辅助指针完成链表的遍历Boy curBoy=first;while (true){System.out.printf("当前小孩的编号为:%d\n",curBoy.no);if(curBoy.next==first){break;}//后移辅助指针curBoy=curBoy.next;}}/**** @param startNo* startNo表示从第几个小孩开始报数* @param countNum* countNo表示一次数几下* @param nums* nums表示一个圈中初始有几个孩子(结点)*///根据用户输入,指定小孩出圈的顺序,也是整个约瑟夫问题的核心public void countBoy(int startNo,int countNum,int nums){//首先进行数据校验if(first==null||startNo<1||startNo>nums){System.out.println("数据输入有误,请重新输入");return;}//创建辅助指针,帮助完成小孩出圈Boy helper=first;//开始时将辅助指针指向环形链表的最后一个结点while (true){if(helper.next==first){break;}helper=helper.next;}//因为有时题目开始报数的并不是1,所以应该先让first和helper同时移动startNo-1次for (int j=0;j<startNo-1;j++){first=first.next;helper=helper.next;}//当小孩报数时,让first和helper指针同时移动countNum-1次,然后出圈//这里是一个循环操作,直到圈里面的人数只有一个while(true){if (helper==first){//此时表示链表中只有一个结点break;}//让first指针和helper指针同时移动countNum-1次for(int j=0;j<countNum-1;j++){first=first.next;helper=helper.next;}//这时first指向的就是将要出圈的孩子System.out.printf("小孩%d出圈\n",first.no);//这时将first指向的小孩结点出圈first=first.next;helper.next=first;}System.out.printf("最后留在圈中的小孩编号%d\n",first.no);}
}
7.代码测试结果
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=12960:D:\IntelliJ IDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\1\IdeaProjects\algorithm\out\production\algorithm" cn.zzw.algorithm.LinkedList.Josepfu
当前小孩的编号为:1
当前小孩的编号为:2
当前小孩的编号为:3
当前小孩的编号为:4
当前小孩的编号为:5
小孩2出圈
小孩4出圈
小孩1出圈
小孩5出圈
最后留在圈中的小孩编号3Process finished with exit code 0
五、单向环形链表---实现约瑟夫(Josephu)问题相关推荐
- (数据结构与算法)单向环形链表解决约瑟夫问题
约瑟夫(Josephu)问题 Josephu问题为: 设编号为1, 2,- n的n个人围坐一圈,约定编号为k (1<=k<=n) 的人从1开始报数,数到m的那个人出列,它的下一位又从1开始 ...
- java模拟单链表环形链表解决约瑟夫问题
java模拟环形链表解决约瑟夫问题 此文是观看尚硅谷韩老师的数据结构与算法学习视频整理的笔记 约瑟夫问题描述 约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算 ...
- 简洁明了!Java实现单向环形链表以解决约瑟夫环Josepfu问题
文章目录 简单介绍 代码实现 简单介绍 如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点. 单向环形链表应用场景:Josep ...
- 牛客题霸 [ 环形链表的约瑟夫问题] C++题解/答案
牛客题霸 [ 环形链表的约瑟夫问题] C++题解/答案 题目描述 据说著名犹太历史学家 Josephus 有过以下故事:在罗马人占领乔塔帕特后,39 个犹太人与 Josephus 及他的朋友躲到一个洞 ...
- 约瑟夫(环)问题(Josephu)(单向环形链表)
问题描述 代码实现 package com.atguigu.linkedlist;import com.sun.org.apache.bcel.internal.generic.NEW;/*** @创 ...
- 数据结构 - 链表(单向环形链表)(约瑟夫问题)
问题如下(与分析) 构建思路 输入一个数,数到这个数的小孩出圈,出圈顺序的思路 代码实现 根据图解,来一步一步实现 //根据用户输入,计算小孩出圈顺序/**** @param startNo 表示从第 ...
- 双向链表、环形链表及约瑟夫问题
一.双向链表 使用带head头的双向链表实现 - 水浒英雄排行榜管理单向链表的缺点分析: 1)单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找. 2)单向链表不能自我删除,需要靠辅助 ...
- java实现环形链表解决约瑟夫环问题
什么是环形链表? 环形链表就是单向链表的基础上让链表的首尾相连,形成一个环,这就是一个循环链表. 什么是约瑟夫环问题? 约瑟夫环如下: 约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数, ...
- 数据结构:单向环形链表
约瑟夫问题 public class Josephus {public static void main(String[] args){SingleCircleLinkedList single = ...
最新文章
- Amazon SageMaker和NVIDIA NGC加速AI和ML工作流
- [Javascript]怎么样让公告不间断的滚动显示
- jQuery+css+html淘宝购物车模块
- push an existing repository from the command line
- 一个由于Pricing RFC引起的UI超时问题
- JSP,JSF和EL简介
- Asp.net禁用页面缓存的方法总结
- Azkaban 进程和任务监控(任务状态从MySQL同步到SqlServer)
- python股票_python股票 - 随笔分类 - 無碼 - 博客园
- html组合标题,如何组合标题关键词(影响标题的5个因素)
- 古诗词学习-归园田居+牧童+凉州词·其一+马诗+逢雪宿芙蓉山主人+凉州词+别董大+枫桥夜泊+滁州西涧+渔歌子+塞下曲
- 微信小程序--使用本地服务器进行测试开发
- JavaScript自动触发事件
- PHPStorm 显示自动换行
- IDEA解决Python项目如何numpy等安装包的问题
- yj.iOS 仿微信长按摄像点击拍照
- 迎难而上 数据库管理员怎样走向成功?(转)
- jquery中的event
- mysql自增不连续的问题
- 【答学员问】完全零基础培训IT,学习能跟的上吗?
热门文章
- 读“基于深度学习的图像风格迁移研究综述”有感
- java Excel 导入 IllegalStateException 异常处理 不同的数据类型
- getFields()和getDeclaredFields的区别
- HTML中单选框的设置,和提交按钮之间的组合
- JMC | 人工智能在药物发现中的应用:走进广阔的天地
- Failure [DELETE_FAILED_INTERNAL_ERROR]的解决办法
- 【问题收录】Ubuntu Starting LightDM Display Manager fail
- R语言绘制二维密度图
- R包corrplot绘图相关系数矩阵
- 今年1篇Science,2篇NBT,2篇MP,1篇PNAS等11篇文章,遗传发育所白洋组在植物微生物组取得系列进展!