【算法】单向环形链表解决Josephu(约瑟夫)问题

应用场景

n 个小孩标号,逆时针站一圈。从 k 号开始,每一次从当前的小孩逆时针数 m 个,然后让最后这个小孩出列。不断循环上述过程,直到所有小孩出列,由此产生出一个队列编号。

提示

用一个不带头节点的循环链表来处理 Josephu 问题:先构成一个有 n 个节点的单循环链表,然后从 k 节点起从 1 开始计数,记到 m 时对应的节点从链表中删除,然后从下一个节点从 1 开始计数,直到最后一个节点从链表中删除算法结束

单向环形链表

构建一个单向环形链表的思路

1.先创建第一个节点,让 first 指向该节点,并形成环形

2.后面当我们每创建一个新节点,就将该节点加入到已有的环形链表中即可

//添加节点,构建成一个环形链表public void addBoy(int nums) {  //nums代表添加的节点的个数//nums 做一个数据校验if (nums < 1) {System.out.println("nums的值不正确");return;}Boy curBoy = null;  //辅助指针,帮助创建环形链表//使用for循环创建一个环形链表for (int i = 1; i <= nums; i++) {//根据编号,创建节点Boy boy  = new Boy(i);//如果是第一个小孩if (i == 1) {first = boy;first.setNext(first);  //构成一个环curBoy = first;  //让curBoy指向第一个小孩} else {curBoy.setNext(boy);boy.setNext(first);curBoy = boy;}}}

遍历环形链表

1.先让一个辅助变量 curBoy 指向 first 节点

2.然后通过一个 while 循环遍历该环形链表即可,当 curBoy.next == first 时结束

//遍历当前环形链表public void showBoy() {//判断链表是否为空if (first == null) {System.out.println("链表为空");return;}//因为first不能动,因此我们使用辅助指针完成遍历Boy curBoy = first;while (true) {System.out.printf("小孩的编号为%d\n", curBoy.getNo());if (curBoy.getNext() == first) {break;}curBoy = curBoy.getNext();  //让curBoy后移}}

根据用户输入,生产一个小孩出圈的顺序

1.需要创建一个辅助指针 helper ,事先应该指向环形链表的最后这个节点

2.在报数前,先让 first 和 helper 移动 k-1 次

3.当小孩报数时,让 first 和 helper 指针同时移动 m-1 次

4.这时就可以将 first 指向的小孩节点出圈

first = first.next;

helper.next = first

原来 first 指向的节点就没有任何引用,就会被回收

//根据用户输入,计算小孩出圈顺序public void  countBoy(int startNo, int countNum, int nums) {//先对数据进行校验if (first == null || startNo < 1 || startNo > nums) {System.out.println("输入的参数有误,请重新输入");return;}//创建一个辅助指针,帮助完成小孩出圈Boy helper = first;//需要创建一个辅助指针 helper ,事先应该指向环形链表的最后这个节点while(true) {if (helper.getNext() == first) {break;}helper = helper.getNext();}//小孩报数之前,让 first 和 helper 指针移动 k-1 次for (int j = 0; j < startNo - 1; j++) {first = first.getNext();helper = helper.getNext();}//当小孩报数时,让 first 和 helper 指针同时移动 m-1 次,然后出圈//这里是一个循环操作,直到圈中只有一个节点while (true) {if (helper == first) {  //说明圈中只有一个节点break;}//让 first 和 helper 指针同时移动 countNum - 1for (int j = 0; j < countNum - 1; j++) {first = first.getNext();helper = helper.getNext();}//这时 first 指向的节点就是要出圈的小孩节点System.out.printf("小孩%d出圈\n", first.getNo());//这时将 first 指向的小孩节点出圈first = first.getNext();helper.setNext(first);}System.out.printf("最后留在圈中的小孩编号%d\n", first.getNo());}

Josephu 问题的解决以及测试

public class Josephu {public static void main(String[] args) {//测试一把,看看构建环形链表和遍历是否okCircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();circleSingleLinkedList.addBoy(5);circleSingleLinkedList.showBoy();System.out.println();//测试一把小孩出圈是否正确circleSingleLinkedList.countBoy(1,2,5);System.out.println();}
}//创建一个环形的单向链表
class CircleSingleLinkedList {//创建一个first节点,当前没有编号private Boy first = new Boy(-1);//添加节点,构建成一个环形链表public void addBoy(int nums) {  //nums代表添加的节点的个数//nums 做一个数据校验if (nums < 1) {System.out.println("nums的值不正确");return;}Boy curBoy = null;  //辅助指针,帮助创建环形链表//使用for循环创建一个环形链表for (int i = 1; i <= nums; i++) {//根据编号,创建节点Boy boy  = new Boy(i);//如果是第一个小孩if (i == 1) {first = boy;first.setNext(first);  //构成一个环curBoy = first;  //让curBoy指向第一个小孩} else {curBoy.setNext(boy);boy.setNext(first);curBoy = boy;}}}//遍历当前环形链表public void showBoy() {//判断链表是否为空if (first == null) {System.out.println("链表为空");return;}//因为first不能动,因此我们使用辅助指针完成遍历Boy curBoy = first;while (true) {System.out.printf("小孩的编号为%d\n", curBoy.getNo());if (curBoy.getNext() == first) {break;}curBoy = curBoy.getNext();  //让curBoy后移}}//根据用户输入,计算小孩出圈顺序public void  countBoy(int startNo, int countNum, int nums) {//先对数据进行校验if (first == null || startNo < 1 || startNo > nums) {System.out.println("输入的参数有误,请重新输入");return;}//创建一个辅助指针,帮助完成小孩出圈Boy helper = first;//需要创建一个辅助指针 helper ,事先应该指向环形链表的最后这个节点while(true) {if (helper.getNext() == first) {break;}helper = helper.getNext();}//小孩报数之前,让 first 和 helper 指针移动 k-1 次for (int j = 0; j < startNo - 1; j++) {first = first.getNext();helper = helper.getNext();}//当小孩报数时,让 first 和 helper 指针同时移动 m-1 次,然后出圈//这里是一个循环操作,直到圈中只有一个节点while (true) {if (helper == first) {  //说明圈中只有一个节点break;}//让 first 和 helper 指针同时移动 countNum - 1for (int j = 0; j < countNum - 1; j++) {first = first.getNext();helper = helper.getNext();}//这时 first 指向的节点就是要出圈的小孩节点System.out.printf("小孩%d出圈\n", first.getNo());//这时将 first 指向的小孩节点出圈first = first.getNext();helper.setNext(first);}System.out.printf("最后留在圈中的小孩编号%d\n", first.getNo());}
}//创建一个Boy类,表示一个节点
class Boy{private int no;  //编号private Boy next;  //指向下一节点,默认为nullpublic Boy(int no) {this.no = no;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public Boy getNext() {return next;}public void setNext(Boy next) {this.next = next;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1489393.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

电脑为什么会出现“找不到msvcr120.dll无法执行代码”?如何解决msvcr120.dll丢失错误

在使用电脑的过程中不知带大家有没有遇到过“找不到msvcr120.dll无法执行代码”的错误提示的情况&#xff0c;出现这样的情况大家都有什么解决办法可以解决&#xff1f;有什么办法能够帮助大家修复丢失的msvcr120.dll文件。接下来这篇文章就将教大家修复“找不到msvcr120.dll无…

2. SDK分析

1. 概述 恒玄bes2700 sdk属于恒玄面向耳机市场的sdk&#xff0c;主要参考《BES_TWS_Software_Development_User_Manual_v1.2.pdf》 SDK由恒玄提供&#xff0c;版本《best1603_ibrt_anc_20240124_207ba3fb90.tar》 2. 文件树结构 - “apps” mainly stores upper-layer applicat…

NRK2202语音识别芯片在车载分氛围灯的应用方案

一、开发背景 随着汽车从单纯的交通工具向智能化、个性化生活空间的转变&#xff0c;车内环境营造成为了提升驾乘体验的关键一环。氛围灯&#xff0c;不仅能够根据驾驶模式、音乐节奏乃至乘客情绪变换色彩与亮度&#xff0c;更承载着营造温馨、浪漫或激情氛围的重任。然而&…

[Windows CMD] 查看网络配置 ipconfig

ipconfig 是一个网络命令工具&#xff0c;用于显示所有适配器&#xff08;网络接口&#xff09;的 IPv4 和 IPv6 配置信息。这个命令在 Windows 操作系统中非常常用&#xff0c;也存在于其他一些基于 IP 的网络系统中&#xff0c;如 macOS 和 Linux&#xff08;在这些系统中通常…

C++ //练习 15.30 编写你自己的Basket类,用它计算上一个练习中交易记录的总价格。

C Primer&#xff08;第5版&#xff09; 练习 15.30 练习 15.30 编写你自己的Basket类&#xff0c;用它计算上一个练习中交易记录的总价格。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块&#xff1a; /********************…

vue3 父组件 props 异步传值,子组件接收不到或接收错误

1. 使用场景 我们在子组件中通常需要调用父组件的数据&#xff0c;此时需要使用 vue3 的 props 进行父子组件通信传值。 2. 问题描述 那么此时问题来了&#xff0c;在使用 props 进行父子组件通信时&#xff0c;因为数据传递是异步的&#xff0c;导致子组件无法成功获取数据…

ueditor跨域问题解决

ueditor解决跨域问题 问题&#xff1a;1.在引用vue-ueditor-wrap后&#xff0c;上传图片和附件出现跨域问题&#xff0c;前端引用了webpack去解决跨域问题&#xff0c;但仍然存在跨域问题&#xff1f; ueditor是百度的富文本&#xff0c;功能较多但资料不够全&#xff0c;因为…

中国医疗AI领头羊讯飞医疗:最新招股书显示前三月收入破亿大关!

讯飞医疗&#xff0c;医疗AI创新企业&#xff0c;收入领先市场。计划港交所上市&#xff0c;用于研发升级、产品扩展及并购。市场潜力巨大&#xff0c;未来发展可期&#xff0c;将成医疗AI璀璨明星。 各位看官&#xff0c;最近科技圈儿又有大新闻啦&#xff01;讯飞医疗科技股份…

【Git】不同区域撤销代码{reset、revert}

工作区【磁盘】 关于GIt&#xff0c;当你在工作区也就是硬盘中修改文件内容&#xff0c;也就是下图的状态。 若你需要撤销此次修改&#xff0c;用到的命令就是 git checkout <changed_file> git restore <changed_file> #推荐 因为checkout在分支中也是切换分…

浅析JWT原理及牛客出现过的相关面试题

原文链接&#xff1a;https://kixuan.github.io/posts/f568/ 对jwt总是一知半解&#xff0c;而且项目打算写个关于JWT登录的点&#xff0c;所以总结关于JWT的知识及网上面试考察过的点 参考资料&#xff1a; Cookie、Session、Token、JWT_通俗地讲就是验证当前用户的身份,证明-…

关键词查找【Boyer-Moore 算法】

1、【Boyer-Moore 算法】 【算法】哪种算法有分数复杂度&#xff1f;- BoyerMoore字符串匹配_哔哩哔哩_bilibili BM算法的精华就在于BM(text, pattern),也就是BM算法当不匹配的时候一次性可以跳过不止一个字符。即它不需要对被搜索的字符串中的字符进行逐一比较&#xff0c;而…

JavaDS —— 排序

排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序&a…

1858. 数组查找及替换

问题描述 给定某整数数组和某一整数 b 。 要求删除数组中可以被 b 整除的所有元素&#xff0c;同时将该数组各元素按从小到大排序。如果数组元素数值在 &#x1d434;‘ 到 Z 的 ASCII 之间&#xff0c;替换为对应字母。 元素个数不超过 100&#xff0c;&#x1d44f; 在 1 …

浅谈HOST,DNS与CDN

首先这个是网络安全的基础&#xff0c;需得牢牢掌握。 1.什么是HOST HOSTS文件&#xff1a; 定义&#xff1a; HOSTS文件是一个操作系统级别的文本文件&#xff0c;通常位于操作系统的系统目录中&#xff08;如Windows系统下的C:\Windows\System32\drivers\etc\hosts&#xf…

Redis底层数据结构的实现

文章目录 1、Redis数据结构1.1 动态字符串1.2 intset1.3 Dict1.4 ZipList1.5 ZipList的连锁更新问题1.6 QuickList1.7 SkipList1.8 RedisObject 2、五种数据类型2.1 String2.2 List2.3 Set2.4 ZSET2.5 Hash 1、Redis数据结构 1.1 动态字符串 Redis中保存的Key是字符串&#xf…

《通讯世界》是什么级别的期刊?是正规期刊吗?能评职称吗?

问题解答 问&#xff1a;《通讯世界》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《通讯世界》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a;科学技术部 主办单位&#xff1a;中国科学技…

chrome浏览器驱动(所有版本)

chrome浏览器驱动 114之前版本 https://chromedriver.storage.googleapis.com/index.html 125以后 125以后版本下载链接在此&#xff0c;只有后面status是绿色对勾的才可以下载&#xff0c;驱动大版本一致就可以使用&#xff0c;不需版本号一模一样&#xff1b;下载所需版本只…

安装CUDA Cudnn Pytorch(GPU版本)步骤

一.先看自己的电脑NVIDIA 支持CUDA版本是多少&#xff1f; 1.打开NVIDIA控制面板 2.点击帮助---系统信息--组件 我的支持CUDA11.6 二.再看支持Pytorch的CUDA版本 三.打开CUDA官网 下载CUDA 11.6 下载好后&#xff0c;安装 选择 自定义 然后安装位置 &#xff08;先去F盘…

一天搞定React(5)——ReactRouter(下)【已完结】

Hello&#xff01;大家好&#xff0c;今天带来的是React前端JS库的学习&#xff0c;课程来自黑马的往期课程&#xff0c;具体连接地址我也没有找到&#xff0c;大家可以广搜巡查一下&#xff0c;但是总体来说&#xff0c;这套课程教学质量非常高&#xff0c;每个知识点都有一个…

C++ 基础练习 - Chapter 7 (英文版)

Review Questions: 7.1 What is operator overloading? Answer: The mechanism of giving special meaning to an operator is known as operator overloading. 7.2 Why is it necessary to overloading an operator? Answer: We can almost create a new language of …