单向环形链表

  • 一、单向环形链表应用场景
  • 二、单向环形链表介绍
  • 三、单向环形链表代码实现
    • 1、代码实现思路
    • 2、代码实现

一、单向环形链表应用场景

提起单向环形链表,就不得不说约瑟夫问题,约瑟夫环。什么事约瑟夫问题呢?

1、约瑟夫问题(有时也称为约瑟夫斯置换,是一个计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。又称“丢手绢问题”.)

2、约瑟夫问题起源
据说,著名犹太历史学家Josephus,有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人,与Josephus,及他的朋友,躲到一个洞中,39个犹太人,决定宁愿死,也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人,该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友,并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方,才能避免被处决。Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏

3、约瑟夫问题图例

二、单向环形链表介绍

1、入队过程:
2、出队过程:

三、单向环形链表代码实现

1、代码实现思路

1、添加节点,构成环装链表

 public void addKid(int nums){//nums数据校验if(nums<1){System.out.println("数据错误");return;}//辅助指针,帮助构成环Kid curKid=null;//使用for循环来创建环形链表for (int i = 1; i <=nums ; i++) {//根据编号创建小孩节点Kid kid=new Kid(i);//如果是第一个小孩if(i==1){first=kid;first.setNext(first);curKid=first;//让curKid指向第一个小孩}else{curKid.setNext(kid);//curkid指针指向下一个孩子kid.setNext(first);//再指回firstcurKid=kid;}}}

2、遍历当前链表

  public void showKid(){//判断链表是否为空if(first==null){System.out.println("链表为空");return;}//因为first不能动,需要创建一个帮助指针来帮助遍历Kid curKid=first;while (true){System.out.printf("小孩的编号%d\n",curKid.getNo());if(curKid.getNext()==first){//说明已经遍历完毕break;}curKid=curKid.getNext();//curKid向后移}}

3、计算节点出圈顺序

/**** @param startNo   表示从第几个小孩开始数数* @param countNum  表示数几下* @param nums      表示最初有几个小孩在圈中*/public void countKid(int startNo,int countNum,int nums) {if (first == null || startNo < 1 || startNo > nums) {System.out.println("输入的数据错误");return;}//创建一个辅助指针帮助小孩出圈Kid helper = first;while (true) {if (helper.getNext() == first) {//说明已经遍历完毕break;}helper = helper.getNext();}//让小孩报数前先让frist和helper指针移动k-1次(比如报2次数,实际指针只移动了一下)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("出圈的小孩\n", first.getNo());//first指向的节点出圈first = first.getNext();helper.setNext(first);}System.out.printf("最后留在圈里的节点%d\n", first.getNo());}

2、代码实现

完整代码

package sparsearray;/*** @author shkstart* @create 2021-08-08 16:22*/
public class Josepfu {public static void main(String[] args) {CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();circleSingleLinkedList.addKid(5);circleSingleLinkedList.showKid();circleSingleLinkedList.countKid(1,2,5);}
}
//创建一个环形的单向链表
class CircleSingleLinkedList{//创建一个first节点,当前没有编号private Kid first=null;//添加小孩节点,构成环装链表public void addKid(int nums){//nums数据校验if(nums<1){System.out.println("数据错误");return;}//辅助指针,帮助构成环Kid curKid=null;//使用for循环来创建环形链表for (int i = 1; i <=nums ; i++) {//根据编号创建小孩节点Kid kid=new Kid(i);//如果是第一个小孩if(i==1){first=kid;first.setNext(first);curKid=first;//让curKid指向第一个小孩}else{curKid.setNext(kid);//curkid指针指向下一个孩子kid.setNext(first);//再指回firstcurKid=kid;}}}//遍历当前链表public void showKid(){//判断链表是否为空if(first==null){System.out.println("链表为空");return;}//因为first不能动,需要创建一个帮助指针来帮助遍历Kid curKid=first;while (true){System.out.printf("小孩的编号%d\n",curKid.getNo());if(curKid.getNext()==first){//说明已经遍历完毕break;}curKid=curKid.getNext();//curKid向后移}}//计算小孩出圈顺序/**** @param startNo   表示从第几个小孩开始数数* @param countNum  表示数几下* @param nums      表示最初有几个小孩在圈中*/public void countKid(int startNo,int countNum,int nums) {if (first == null || startNo < 1 || startNo > nums) {System.out.println("输入的数据错误");return;}//创建一个辅助指针帮助小孩出圈Kid helper = first;while (true) {if (helper.getNext() == first) {//说明已经遍历完毕break;}helper = helper.getNext();}//让小孩报数前先让frist和helper指针移动k-1次(比如报2次数,实际指针只移动了一下)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("出圈的小孩\n", first.getNo());//first指向的节点出圈first = first.getNext();helper.setNext(first);}System.out.printf("最后留在圈里的节点%d\n", first.getNo());}
}
//创建Kid类,表示节点
class Kid{private int no;//小孩编号private Kid next;//表示下一个节点public Kid(int no) {this.no = no;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public Kid getNext() {return next;}public void setNext(Kid next) {this.next = next;}
}

数据结构——>单向环形链表相关推荐

  1. 数据结构:单向环形链表

    约瑟夫问题 public class Josephus {public static void main(String[] args){SingleCircleLinkedList single = ...

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

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

  3. 五、单向环形链表---实现约瑟夫(Josephu)问题

    使用单向环形链表实现约瑟夫(Josephu)问题 1.约瑟夫(Josephu)问题描述 Josephu 问题为:设编号为 1,2,- n 的 n 个人围坐一圈,约定编号为 k(1<=k<= ...

  4. 简洁明了!Java实现单向环形链表以解决约瑟夫环Josepfu问题

    文章目录 简单介绍 代码实现 简单介绍 如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点. 单向环形链表应用场景:Josep ...

  5. 数据结构 - 链表(单向环形链表)(约瑟夫问题)

    问题如下(与分析) 构建思路 输入一个数,数到这个数的小孩出圈,出圈顺序的思路 代码实现 根据图解,来一步一步实现 //根据用户输入,计算小孩出圈顺序/**** @param startNo 表示从第 ...

  6. 图解Java数据结构之环形链表

    本篇文章介绍数据结构中的环形链表. 介绍 环形链表,类似于单链表,也是一种链式存储结构,环形链表由单链表演化过来.单链表的最后一个结点的链域指向NULL,而环形链表的建立,不要专门的头结点,让最后一个 ...

  7. 约瑟夫(环)问题(Josephu)(单向环形链表)

    问题描述 代码实现 package com.atguigu.linkedlist;import com.sun.org.apache.bcel.internal.generic.NEW;/*** @创 ...

  8. (四)数据结构与算法-链表

    链表介绍 链表是有序的列表,但是它在内存中存储如下: 链表是以节点的方式来存储 每个节点包含data域,next域:指向下一个节点 如图:发现链表的各个节点不一定是连续存储 链表分带头节点的链表和没有 ...

  9. 牛客题霸 [ 环形链表的约瑟夫问题] C++题解/答案

    牛客题霸 [ 环形链表的约瑟夫问题] C++题解/答案 题目描述 据说著名犹太历史学家 Josephus 有过以下故事:在罗马人占领乔塔帕特后,39 个犹太人与 Josephus 及他的朋友躲到一个洞 ...

  10. 链表(Linked List)之环形链表

    原文地址:传送门 单向环形链表应用场景 Josephu(约瑟夫.约瑟夫环) 问题 Josephu 问题为:设编号为1,2,- n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始 ...

最新文章

  1. 2008年上半年 网络工程师 上下午试卷【附带答案】
  2. mysql索引详细介绍简书_MySql索引详解
  3. nodejs学习资料
  4. PHP条件语句总结,PHP 条件语句基本语法结构
  5. dapper 连接mysql_如何在.NET中使用Dapper处理数据库连接?
  6. 对现有的所能找到的DDOS代码(攻击模块)做出一次分析----自定义攻击篇
  7. 控制台下载vue_DubboAdmin管理控制台
  8. java md2_java中加密的实现方法(MD5,MD2,SHA)
  9. springboot整合canal
  10. 什么是 PostgreSQL 横向子查询?
  11. 相机标定原理介绍(一)
  12. 傅里叶变换,拉普拉斯变换和小波变换
  13. 视频格式mp4转emf
  14. CTF misc图片类总结(入门级)
  15. oracle全量拷贝,oracle数据库expdp异机全量备份
  16. Symbol类型详解
  17. 在记事本中无限循环_意外空间:比恐怖游轮更无解的循环迷宫
  18. redis查看集合中元素的数量,scard
  19. [思语]_我心中的大师
  20. 跨专业考计算机哪个专业好考吗,考研常识:跨专业考研好考专业?

热门文章

  1. IIS------IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决办法
  2. C++day14 学习笔记
  3. sqlserver中系统库的作用
  4. myeclipse 的 restart server和Redeploy/Reload application的区别
  5. 61.Linux/Unix 系统编程手册(下) -- SOCKET: 高级主题
  6. 7.Zeng_Cache(1) --- 简介
  7. react中IOS手机里面两个input同时存在时,聚焦focus失效解决办法
  8. denali vip使用经验
  9. ADO ( 问数据库数据 的编程 接口)
  10. sql2000下 分页存储过程(一)