数据结构——>单向环形链表

2023-11-11

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

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

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);//再指回first
                curKid=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-1
            for (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);//再指回first
                curKid=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-1
            for (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;
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构——>单向环形链表 的相关文章

  • Junit:如何测试从属性文件读取属性的方法

    嗨 我有课ReadProperty其中有一个方法ReadPropertyFile返回类型的Myclass从属性文件读取参数值并返回Myclass目的 我需要帮助来测试ReadPropertyFile方法与JUnit 如果可能的话使用模拟文件
  • 如何通过 javaconfig 使用 SchedulerFactoryBean.schedulerContextAsMap

    我使用 Spring 4 0 并将项目从 xml 移至 java config 除了访问 Service scheduleService 带注释的类来自QuartzJobBean executeInternal 我必须让它工作的 xml 位
  • 为什么 JTables 使 TableModel 在呈现时不可序列化?

    所以最近我正在开发一个工具 供我们配置某些应用程序 它不需要是什么真正令人敬畏的东西 只是一个具有一些 SQL 脚本生成功能并创建几个 XML 文件的基本工具 在此期间 我使用自己的 AbstractTableModel 实现创建了一系列
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • org.apache.hadoop.security.AccessControlException:客户端无法通过以下方式进行身份验证:[TOKEN,KERBEROS] 问题

    我正在使用 java 客户端通过 Kerberos 身份验证安全访问 HDFS 我尝试打字klist在服务器上 它显示已经存在的有效票证 我收到的异常是客户端无法通过以下方式进行身份验证 TOKEN KERBEROS 帮助将不胜感激 这是一
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 在接口中使用默认方法是否违反接口隔离原则?

    我正在学习 SOLID 原则 ISP 指出 客户端不应被迫依赖于他们所使用的接口 不使用 在接口中使用默认方法是否违反了这个原则 我见过类似的问题 但我在这里发布了一个示例 以便更清楚地了解我的示例是否违反了 ISP 假设我有这个例子 pu
  • Java 公历日历更改时区

    我正在尝试设置 HOUR OF DAY 字段并更改 GregorianCalendar 日期对象的时区 GregorianCalendar date new GregorianCalendar TimeZone getTimeZone GM
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 将 MOXy 设置为 JAXB 提供程序,而在同一包中没有属性文件

    我正在尝试使用 MOXy 作为我的 JAXB 提供程序 以便将内容编组 解组到 XML JSON 中 我创建了 jaxb properties 文件 内容如下 javax xml bind context factory org eclip
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • 如何在用户输入数据后重新运行java代码

    嘿 我有一个基本的java 应用程序 显示人们是成年人还是青少年等 我从java开始 在用户输入年龄和字符串后我找不到如何制作它它们被归类为 我希望它重新运行整个过程 以便其他人可以尝试 的节目 我一直在考虑做一个循环 但这对我来说没有用
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • 如何使用mockito模拟构建器

    我有一个建造者 class Builder private String name private String address public Builder setName String name this name name retur
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • 使用 svn 1.8.x、subclise 1.10 的 m2e-subclipse 连接器在哪里?

    我读到 m2e 的生产商已经停止生产 svn 1 7 以外的任何版本的 m2e 连接器 Tigris 显然已经填补了维护 m2e subclipse 连接器的空缺 Q1 我的问题是 使用 svn 1 8 x 的 eclipse 更新 url
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供

随机推荐

  • lowbit

    lowbit用来计算二进制数 从右往左数第一个1与其后面的0组成的数 int lowbit int x return x x x 12 1100 lowbit 12 100 4 7 111 lowbit 7 1 1
  • Flutter优秀第三方常用框架

    名称 GitHub地址 下拉刷新上拉加载 EasyRefresh 下拉刷新上拉加载 PullToRefresh SharedPreferences shared preferences 中国城市选择器 city picker 设备信息 de
  • 硬盘存储知识

    存储知识 内存和外存 硬盘 1 物理磁盘类型 硬盘分为 机械硬盘 HDD 和固态硬盘 SSD 注意 买硬盘的时候要注意转速 机械硬盘是以下三种 物理磁盘类型 SATA盘 物理磁盘类型 SAS盘 物理磁盘类型 NL SAS盘 固态硬盘 物理磁
  • 微信小程序期末大作业 中草药小程序 药海拾遗

    微信小程序期末大作业 中草药小程序 药海拾遗 小程序详情如下 下载链接在文末 学习社区可以自己添加内容 点我下载资源 https download csdn net download weixin 43474701 59675965
  • 【Struts2六】ui标签之form标签及数据回显

    ui标签 用在jsp页面用于回显数据的标签 这些标签是由框架定义的 用来替代原生的标签 ui标签有
  • WPF编程,Live Charts使用说明(11)——基本折线图

    后台 using System using System Windows Controls using System Windows Media using LiveCharts using LiveCharts Wpf namespace
  • Spring整合Druid

    Druid是Java语言中最好的数据库连接池 Druid能够提供强大的监控和扩展功能 Druid是阿里巴巴开源平台上的一个项目 整个项目由数据库连接池 插件框架和SQL解析器组成 该项目主要是为了扩展JDBC的一些限制 可以让程序员实现一些
  • 厉害了|十分钟掌握python3语言特性

    看了王垠的 如何掌握所有程序语言 感触甚深 如果说程序语言有其通用规律的话 那就是语言特性 也就是这些语言的通用概念 这些概念的具体语法的形式可能都不一样 但是所内涵的功能是一致的 比如英语中的bird和汉语中鸟 其实指的都是同一种事物 关
  • python自动生成电子邮箱'@hotmail.com', '@msn.com', '@yahoo.com', '@gmail.com', '@aim.com', '@aol.com', '@mail

    def getAutoEmail self 自动生成电子邮箱 Fist email join random sample string ascii letters string digits 9 last emailList hotmail
  • 使用Docker及Docker-compose部署SpringBoot项目

    1 环境准备 Windows下安装Docker需要WSL2及Hyper v Windows家庭版没有 Linux下安装Docker 参考官方文档 Install Docker Engine Docker Documentation 根据自己
  • Poi实现Excel导出

    Poi实现Excel导出 Appache Poi提供了HSSFWorkbook操作2003版本的Excel文件 XSSFWorkbook操作2007版Excel文件 简单的具体实现在网上有很多案例可以参考学习 我就不写入门案例了 下面我会将
  • AutoML系列

    本文是对 Neural Architecture Search A Survey 的翻译 这篇Paper 很好的总结分析了 NAS 这一领域的研究进展 摘要 在过去几年中 深度学习在各种任务上 例如图像识别 语音识别和机器翻译 取得了显著进
  • 利用javascript的算术运算符获取一个数字的每位数字

  • element tree 树形控件

    组件 Element 地址 http element eleme io zh CN component tree Tree树形控件
  • 【VAR模型

    向量自回归 VAR 是一种随机过程模型 用于捕获多个时间序列之间的线性相互依赖性 VAR 模型通过允许多个进化变量来概括单变量自回归模型 AR 模型 VAR 中的所有变量都以相同的方式进入模型 每个变量都有一个方程式 根据其自身的滞后值 其
  • IBM MQ 故障诊断(一)

    说明 本文主要是针对运维人员的手册 前面部分主要是应用三板斧的方式 后面的步骤可能会发散和具体深入一些 不过也不是严格的划分 读者就当看一遍杂文的方式来看待此文吧 一 队列管理器的启停 QMGR的启停是故障诊断中遇到最多的需求之一 启动队列
  • 【C语言】可变参数列表

    文章目录 前言 一 可变参数列表是什么 二 怎么用可变参数列表 三 对于宏的深度剖析 隐式类型转换 对两个函数的重新认知 总结 前言 可变参数列表 使用起来像是数组 学习过函数栈帧的话可以发现实际上他也就是在栈区定义的一块空间当中连续访问
  • 无服务器编程语言,腾讯云之无服务器云函数运行golang程序-Go语言中文社区

    使用腾讯的 无服务器云函数启动了一个服务 用golang代码生成以太坊的私钥跟地址 genEthAddr png 无服务器云函数是什么 腾讯云的无服务器云函数 跟 aws lambda类似 把一段代码放到云函数服务器上 设定好访问路径 就可
  • 高等代数 多项式环(第7章)5* 结式与域

    一 结式 1 概念 2 结式与公共复根 1 多项式存在公共复根的判定 定理1 设 f x a
  • 数据结构——>单向环形链表

    单向环形链表 一 单向环形链表应用场景 二 单向环形链表介绍 三 单向环形链表代码实现 1 代码实现思路 2 代码实现 一 单向环形链表应用场景 提起单向环形链表 就不得不说约瑟夫问题 约瑟夫环 什么事约瑟夫问题呢 1 约瑟夫问题 有时也称