链表(Linked List)之环形链表

原文地址:传送门

单向环形链表应用场景

img

Josephu(约瑟夫、约瑟夫环) 问题

Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

提示:

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

img

Josephu 问题为:设编号为1,2,… nn个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

n = 5 , 即有5个人 
k = 1, 从第一个人开始报数
m = 2, 数2下

img

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

  1. 先创建第一个节点, 让 first 指向该节点,并形成环形
  2. 后面当我们每创建一个新的节点,就把该节点,加入到已有的环形链表中即可.

遍历环形链表

  1. 先让一个辅助指针(变量) curBoy,指向first节点
  2. 然后通过一个while循环遍历 该环形链表即可 curBoy.next == first 结束

环形链表_约瑟夫问题分析图解和实现

img

根据用户的输入,生成一个小孩出圈的顺序
n = 5 , 即有5个人 
k = 1, 从第一个人开始报数
m = 2, 数2下
  1. 需求创建一个辅助指针(变量) helper , 事先应该指向环形链表的最后这个节点. 补充: 小孩报数前,先让 firsthelper 移动 k - 1
  2. 当小孩报数时,让firsthelper 指针同时 的移动 m - 1
  3. 这时就可以将first 指向的小孩节点 出圈 first = first .next helper.next = first
    原来first 指向的节点就没有任何引用,就会被回收

出圈的顺序 2->4->1->5->3

一直丢手绢

哔哩哔哩动画

代码

package com.atguigu.linkedlist;/*** ClassName:  <br/>* Description:  <br/>* Date: 2021-02-19 15:22 <br/>* @project data_algorithm* @package com.atguigu.linkedlist*/public class Josepfu {public static void main(String[] args) {// 测试一把看看构建环形链表,和遍历是否okCircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();circleSingleLinkedList.addBoy(125);// 加入5个小孩节点circleSingleLinkedList.showBoy();//测试一把小孩出圈是否正确circleSingleLinkedList.countBoy(10, 20, 125); // 2->4->1->5->3//String str = "7*2*2-5+1-5+3-3";}}// 创建一个环形的单向链表
class CircleSingleLinkedList {// 创建一个first节点,当前没有编号private Boy first = null;// 添加小孩节点,构建成一个环形的链表public void addBoy(int 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后移}}// 根据用户的输入,计算出小孩出圈的顺序/**** @param startNo*            表示从第几个小孩开始数数* @param countNum*            表示要数几下* @param nums *            表示最初有多少小孩在圈中*/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) { // 说明helper指向最后小孩节点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.mzph.cn/news/455098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot 单测加入参数_spring-boot-单元测试参数数

简单案例RunWith(Parameterized.class)public class ParameterTest {// 2.声明变量存放预期值和测试数据private String firstName;private String lastName;//3.声明一个返回值 为Collection的公共静态方法&#xff0c;并使用Parameters进行修饰Parameterized.Parameterspubli…

H.264/AVC 标准中CAVLC 和CABAC 熵编码算法研究

http://www.paper.edu.cn/index.php/default/releasepaper/downPaper/200903-146

python ==》 元组

为何要有元组 &#xff0c;() 可存放多个值 元组不可变 更多的是用来查询t (1,[1,3],sss,(1,2)) #t tuple(1,[1,3],sss,(1,2))print (type(t))元组可以作为字典的keyd{(1,2,3):zcx}print(d,type(d),d[(1,2,3)])索引取值d (1,2,3,4,5)print(d[1])切片goods (iphone,lenove,…

免费SSL证书(支持1.0、1.1、1.2)

由于公司要开发微信小程序&#xff0c;而微信小程序的接口需要https协议的&#xff0c;并且要支持TLS1.0、TLS1.1、TLS1.2。如果仅仅是为了开发小程序&#xff0c;安全等级又不用太高&#xff0c;可以选择免费的SSL证书 在这里选择腾讯云的证书&#xff0c;申请在 https://cons…

viewsource和viewparsed_Network Panel说明

一、chrome Developer Tools&#xff1a;Network Panel从网络面板中可以获取很多有用信息&#xff0c;如详细的时间数据&#xff0c;http请求头响应头&#xff0c;cookies&#xff0c;WebSocket数据。通过分析这些数据&#xff0c;可以知道哪个资源加载耗时最久&#xff0c;谁发…

使用栈来完成一个表达式的结果

原文地址:传送门 使用栈来完成一个表达式的结果 使用栈完成计算 一个表达式的结果 7*2*2-51-53-4 &#xff1f; 32*6-2[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XzPnJzRe-1614845779689)(https://victorfengming.gitee.io/data_algorithm/i…

JM与h264标准中的关键字说明

有些乱&#xff0c;先存着&#xff0c;留着看 如何结合H.264标准看JM代码》这个web文件&#xff0c;大家都应该有了吧。不过&#xff0c;那个web文档是“H.264乐园”群中聊天的内容 1、一个sps后&#xff0c;有若干个pps吗&#xff1f; 这主要又编码器决定&#xff0c;但J…

云计算(cloud computing)十大问答

本文讲的是云计算&#xff08;cloud computing&#xff09;十大问答&#xff0c;【IT168 资讯】云计算这个新名词最近甚嚣尘上&#xff0c;最近周围不少朋友都在谈&#xff0c;有必要写一个关于云计算的科普了。  一般的业界比较喜欢用一些新名词来体现 自己的战略眼光和与对…

3150cdn打印机清零 hl_兄弟HL-3150/3140彩色打印机粉盒清零方法,我们提前了解一下...

原标题&#xff1a;兄弟HL-3150/3140彩色打印机粉盒清零方法&#xff0c;我们提前了解一下对于兄弟品牌的打印机&#xff0c;相信各位经销商朋友都遇到过&#xff0c;更换新的粉盒或者加粉后还会提示墨粉不足、更换碳粉盒、更换硒鼓。这个情况需要在机器上操作清零&#xff01;…

Python 关于bytes类方法对数字转换的误区, Json的重要性

本文起源于一次犯错, 在发觉bytes()里面可以填数字, 转出来的也是bytes类型, 就心急把里面的东西decode出来. 结果为空.搞来搞去以为是命令不熟练事实上错在逻辑.a1 bytes(11, encodingutf-8) print(a1)b1 a1.decode()print(b1)a2 bytes(11) print(a2)b2 a2.decode() print…

前缀中缀后缀表达式的计算求值

原文在这里 表达式 前缀表达式(波兰表达式) 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前举例说明&#xff1a; (34)5-6 对应的前缀表达式就是 - 3 4 5 6 前缀表达式求值 前缀表达式的计算机求值 从右至左扫描表达式&#xff0c;遇到数字时&#xff0c;将数…

psnr 计算

PSNR是“Peak Signal to Noise Ratio”的缩写&#xff0c;峰值信噪比。psnr一般是用于最大值信号和背景噪音之间的一个工程项目。 PSNR计算公式如下&#xff1a; 8bits表示法中&#xff0c;peak的最大值为255&#xff1b;MSE指Mean Square Error&#xff08;均方误差&#xff0…

光源时间_缩短背光源的使用寿命的原因

许多场所都会使用到led这种产品&#xff0c;这种产品经常用于背光的照亮中。但是由于使用led的局限性较大&#xff0c;所以led逐渐被背光源这种产品所代替&#xff0c;常常用于背景的照亮让宣传图可以展现出更好的视觉&#xff0c;这也是许多人选择背光源的原因。那么&#xff…

《结对-贪吃蛇-需求分析》

结对编程&#xff1a;贪吃蛇项目 准备阶段&#xff1a;安装Python、pygame 编写阶段&#xff1a;1. 设置游戏窗口 2. 设置游戏必要功能&#xff1a; a)开始、暂停、退出按钮 b)贪吃蛇身体 c)食物 d)移动贪吃蛇所需按键 3. 完善游戏&#xff1a;添加游戏时间、贪吃蛇失败次数…

视频中场的问题2009-04-03 19:38(一)

视频中场的问题2009-04-03 19:38(一) 场的用途&#xff1a; 让25帧/秒的电视画面帧速率&#xff0c;变为50帧/秒。使观众感受到更加流畅的画面。 (二) 场的由来&#xff1a; 在电视制作的时候&#xff0c;电视扫描一副画面的时间根据当地交流电源的频率来确定。比如中国交流电源…

递归应用场景和调用机制

原文链接:传送门 递归 迷宫问题(回溯) 概念 简单呐的说: 递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同时让代码变得简洁. 案例-递归调用机制 打印问题 public static void test(int n){if(n>2){test(n-1);}System.out.print…

在vivado里用rtl描述_如何利用Vivado HLS处理许多位准确或任意精度数据类型

我们在设计硬件时&#xff0c;它往往是要求更精确的位宽。例如&#xff0c;一个filter的输入是12位和一个累加器的结果只需要一个最大范围为27位。然而对于硬件设计来说&#xff0c;使用标准的C数据类型会造成硬件成本的浪费。这就会造成我们要使用更多的LUT和寄存器&#xff0…

Spring4.0之四:Meta Annotation(元注解)

Spring框架自2.0开始添加注解的支持&#xff0c;之后的每个版本都增加了更多的注解支持。注解为依赖注入&#xff0c;AOP&#xff08;如事务&#xff09;提供了更强大和简便的方式。这也导致你要是用一个相同的注解到许多不同的类中去。这篇文章介绍meta annotation来解决这个问…

八皇后问题分析与Java实现

原文链接:传送门 八皇后问题 八皇后问题&#xff0c;是一个古老而著名的问题&#xff0c;是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯贝瑟尔于1848年提出&#xff1a;在88格的国际象棋上摆放八个皇后&#xff0c;使其不能互相攻击&#xff0c;即&#xff1a;任意两个…

各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

编解码学习笔记&#xff08;一&#xff09;&#xff1a;基本概念 媒体业务是网络的主要业务之间。尤其移动互联网业务的兴起&#xff0c;在运营商和应用开发商中&#xff0c;媒体业务份量极重&#xff0c;其中媒体的编解码服务涉及需求分析、应用开发、释放license收费等等。最…