环形单向链表:守卫连接的一个单向链表,每个节点中有其变量和一个指针指向下一个节点。头节点可有可无,此处写的没有头节点。

创建,先创建一个没有数据的first节点表示整个链表的第一个节点

添加,此处的添加与之前的不同,这里的每个节点比较简单且无顺序可言,可直接生成环形链表而非和之前一样一个个添加。所以此处传入函数的参数为节点个数,用for循环生成循环单链表。其中生成第一个节点时需要把first节点的数据替换掉,因此在i=1的时候需要额外判断一步将生成的新节点替换掉first中的无数据。并将next连到自己身上,并将temp赋值first。其他的节点只需生成新节点后将其赋值给temp的next并将新节点的next连到第一个节点即可,最后也要将temp后移、

 public void add(int n){
if(n<2){
System.out.println("人数太少");
return;
}
Boy temp=null;
for (int i=1;i<=n;i++){ Boy boy=new Boy(i);
if(i==1){
first=boy;
first.next=first;
temp=first;
}else {
temp.next=boy;
boy.next=first;
temp=temp.next;
}
}
}

遍历,判断链表不为空后利用辅助节点等于first开始不断后移遍历,辅助节点为最后一个时结束遍历

其中,辅助节点temp.next=first时temp为最后一个节点,first,next=null时链表为空

    public void list(){
if(first.next==null){
System.out.println("链表为空");
}
Boy temp=first;
while (true){
System.out.println(temp.no);
if(temp.next==first) break;
temp=temp.next;
}
}

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

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

思路:设置一个helper变量,指向first的后一个即链表的最后一个节点。helper节点用while函数使其指向链表中的最后一个节点,即当其next为first时它为最后一个节点。

因为要从编号n开始数,数k下,所以这个函数需要的参数有startno(开始报数的编号)、countnum(报的数字)、nums(总的节点数)

需要在最开始检查几个变量的合理性,我自己写的时候虽然不影响整体结果但漏考虑了几种条件。老师此处的判断有如下几个:链表为空,开始编号小于1,开始编号大于总数

先将helper和first共同后移countnum-1个,让first到达开始报数的位置,接下来的程序都是重复的程序,不断找出一个个节点将其踢出链表。所以此处用一个while函数编写,其中包含了几个步骤:

1、设置跳出函数的判断条件,当链表中只剩一个节点时,跳出while循环,即first=helper时跳出循环。

2、以for循环不断报数,让helper和first后移countnum个,此时first指的节点便为要踢出链表的节点。这里我们让first再往后移一次,则现在要删除的节点位于helper和first之间,此时让first与helper连起来即可。

代码如下:

public void count(int startNo,int countNum,int nums){
if(nums<1||nums<startNo||first==null||startNo<1){
System.out.println("数据输入有误");
return;
}
Boy helper=first;
while (true){
if(helper.next==first) break;
helper=helper.next;
}
for (int i=0;i<startNo-1;i++){
helper=helper.next;
first=first.next;
}
while(true){
if(first==helper){
break;
}
for (int i=0;i<countNum-1;i++){
helper=helper.next;
first=first.next;
}
System.out.println(helper.next.no);
first=first.next;
helper.next=first; }
System.out.println(first.no);
}

其实这个问题并不难,用数组等方法也可以轻松做出来。但以此方法一个是了解了链表中的环形链表的结构和创建方式,另一个也是学到了其的应用。

最新文章

  1. 搭建Linux+Jexus+MariaDB+ASP.NET[LJMA]环境
  2. yar框架使用笔记
  3. JS手札
  4. JVM加载类的过程,双亲委派机制中的方法
  5. Spring事务管理者与Spring事务注解--声明式事务
  6. python中subprocess.Popen.poll
  7. BIP_开发案例05_BI Pubisher标准做法以BIP.XML为数据源以BIP.RTF为模板的简单例子(案例)
  8. UVa 1637 (概率) Double Patience
  9. puppet运维配置实列
  10. voijs1883 月光的魔法
  11. Go成功的项目
  12. Tarjan-求强连通分量
  13. 3-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案数据篇(安装配置数据库,使用Navicat for MySQL和手机APP 连接测试)
  14. Intent调用常见系统组件
  15. Electron 发生错误 &quot;Cannot find module app&quot;的解决方案
  16. DevExpress v18.1新版亮点——DevExtreme篇(四)
  17. 网络表示学习Network Representation Learning/Embedding
  18. Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again 问题分析
  19. HTTP tunnel
  20. Chrome浏览器video样式控制-隐藏下载按钮

热门文章

  1. react 高效高质量搭建后台系统 系列 —— 前端权限
  2. 随机森林RF模型超参数的优化:Python实现
  3. 认识Spring MVC-概念-小demo
  4. 0x06_自制操作系统My-OS,IDT,GDT,PIC初始化,实现键盘中断
  5. Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.
  6. Idea External Libraries 没有导入依赖
  7. PostgreSQL 谁堵塞了谁(锁等待检测)- pg_blocking_pids
  8. 【Linux SPI】RFID RC522 设备驱动
  9. Linux操作命令(三)1.more命令 2.less命令 3.head命令 4.tail命令
  10. 使用AJAX绑定点击事件将接口值返回渲染到指定位置