单向环形链表和约瑟夫问题

news2024/9/20 8:54:11

单向环形链表和约瑟夫问题

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

n = 5 , 即有5个人

k = 1, 从第一个人开始报数

m = 2, 数2下

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

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

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

遍历环形链表

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

  2. 然后通过一个while循环遍历该环形链表即可

  3. curBoy.next==first结束

代码实现

// 创建一个环形的单向链表
class CircleSingleLinkedList {
    // 创建一个first节点, 当前没有编号
    private Boy first = new Boy(-1);
​
    // 添加小孩节点,构建一个环形的链表
    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 show(){
        // 判断链表是否为空
        if (first==null){
            System.out.println("没有任何小孩");
            return;
        }
        // 因为first不能动,因此我们仍然使用一个辅助指针完成遍历
        Boy curBoy = first;
        while (true){
            System.out.println("小孩的编号是:"+curBoy.getNo());
            if (curBoy.getNext()==first){// 说明已经遍历完毕
                break;
            }
            curBoy=curBoy.getNext();// curBoy后移
        }
    }
}
​
// 创建一个Boy类,表示一个节点
class Boy {
    private int no;// 编号
    private Boy next;// 指向下一个节点,默认是null
​
    public 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;
    }
}

对以上方法测试

public static void main(String[] args) {
    //测试
    CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
    circleSingleLinkedList.addBoy(25);// 加入5个小孩节点
    circleSingleLinkedList.show();
}

关于出圈问题

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

n = 5 , 即有5个人

k = 1, 从第一个人开始报数

m = 2, 数2下

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

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

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

  4. 这时就可以将first 指向的小孩节点 出圈first = first .next helper.next = first 原来first 指向的节点就没有任何引用,就会被回收

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

代码实现

// 根据用户输入,计算出小孩的出圈顺序
/**
 * @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;
    }
    // 这里做法是先将helper指向first,然后通过遍历 将helper指向最后一个节点
    // 创建辅助指针,帮助小孩完成出圈
    Boy helper = first;//指向环形单链表的最后一个节点
    //创建一个辅助变量helper,事先应该指向环形链表的最后这个节点
    while (true) {
        if (helper.getNext() == first) {// 说明helper指向最后小孩节点
            break;
        }
        helper = helper.getNext();
    }
    // 寻找起始位置,把first定义为起始位置 移动k-1次
    for (int i = 0; i < startNo - 1; i++) {
        first = first.getNext();
        helper = helper.getNext();
    }
    // 当小孩报数时,让first和helper指针同时移动m-1次 然后出圈
    // 这里是一个循环操作,知道圈中只有一个节点
    while (true) {
        if (helper == first) {// 说明圈中只有一个节点
            break;
        }
        // 让first和helper指针同时移动countNum-1次
        for (int i = 0; i < countNum - 1; i++) {
            first = first.getNext();
            helper = helper.getNext();
        }
        // 这时first指向的节点就是要出圈的节点
        System.out.println("小孩" + first.getNo() + "出圈");
        // 这时将first指向的小孩节点出圈
        first = first.getNext();
        helper.setNext(first);
    }
    System.out.println("最后留在圈中的小孩编号是:" + first.getNo());
}
// 这里在main方法里执行
// 测试小孩出圈是否正确
circleSingleLinkedList.countBoy(1,2,5);

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

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

相关文章

ubuntu压缩、归档 tar zip gzip的介绍

不同文件需要使用不同的工具进行压缩和解压&#xff0c;可以使用file文件查看是什么类型的文件 file 文件名如图&#xff0c;在第二行看到这个文件是gzip类型的。 文件&#xff1a;gzip 工具&#xff1a;gunzip gunzip是 gnu unzip的缩写。用来解压gzip压缩包。 解压命令 …

linux 内存管理

0.前言 1.了解Linux内存的管理机制(分段分页) 2.了解虚拟内存和物理内存的映射方式 3.了解操作系统内存与磁盘的交互&#xff08;分页机制---》缺页重读机制&#xff0c;用时拷贝机制) 4.应用程序如何高效使用内存和高级程序的设计方法 1.linux物理使用情况 内核区&#x…

动态站点地图提交百度收录

站点地图&#xff08;sitemap&#xff09;是一个网站的结构化数据&#xff0c;搜索引擎可以通过站点地图迅速了解一个网站的内容&#xff0c;加快搜索引擎收录。 一般来说&#xff0c;站点地图是以.xml结尾的静态化文件&#xff0c;例如个人博客和生化环材网的站点地图链接分别…

【Mysql】事务的四大特性(ACID)

【Mysql】事务的四大特性(ACID) 文章目录【Mysql】事务的四大特性(ACID)1. 概述1.1 并发事务问题1.1.1 脏读1.1.2 不可重复读1.1.3 幻读1.2 事务隔离级别1. 概述 事务的四大特性&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#xff1a;事务是不可分割的最小操作单…

ROS学习寄录2

1 ROS核心概念 1.1 节点&#xff08;Node&#xff09; &#xff08;1&#xff09;执行具体任务的进程、独立运行的可执行文件 &#xff08;2&#xff09;不同节点可以使用不同的语言&#xff0c;可分布式运行在不同的主机 &#xff08;3&#xff09;节点在系统中的名称必须…

MODBUS总线的学习笔记

MODBUS学习记录 下面所有资料均copy于安富莱电子和博客中&#xff0c;仅作为个人学习笔记记录&#xff0c;写的不好请见谅。 1.modbus简介介绍 Modbus 是由 Modicon&#xff08;现为施耐德电气公司的一个品牌&#xff09;在 1979 年发明的&#xff0c;是全球第一个真正 用于…

PowerShell 学习笔记:操作XML文件

XML文件是有一定格式要求的文本文件。百度百科可扩展标记语言 (Extensible Markup Language, XML) &#xff0c;标准通用标记语言的子集&#xff0c;可以用来标记数据、定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 可扩展…

adversarial Learning and attacks 学习笔记

GANs大家是比较熟悉的网络结构&#xff0c;adversarial attacks 也不是很新的概念了。近期的工作有涉及到adversarial attacks&#xff0c;故整理一下学习的内容。 Adversarial Attacks 对抗攻击样本&#xff1a;一张正常的大熊猫图片&#xff08;左图&#xff09;在被加入噪…

Leetcode.1828 统计一个圆中点的数目

题目链接 Leetcode.1828 统计一个圆中点的数目 题目描述 给你一个数组 points&#xff0c;其中 points[i] [xi, yi] &#xff0c;表示第 i个点在二维平面上的坐标。多个点可能会有 相同 的坐标。 同时给你一个数组 queries&#xff0c;其中 queries[j] [xj, yj, rj]&#x…

Feign入门

Feign入门Feign入门Feign代替RestTemplate自定义配置Feign使用优化最佳实践Feign入门 Feign代替RestTemplate RestTemplate方式调用存在的问题 先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; String url "http://userservice/user/" order.ge…

linux(Debian11)安装后安装无线网卡等驱动

在工作和生活中&#xff0c;我们经常会用到linux系统&#xff0c;debian作为一个老牌的程序员常用发行版&#xff0c;自然成为我们的首选。 下面记录一下&#xff0c;安装无线网卡的过程。 首先&#xff0c;可以通过命令查看自己所需要的驱动 lspci -vvv iwlwifi 就是我所需…

机器学习为什么使用归一化? 有哪些归一化算法?

一、归一化的基本介绍 1. Why 归一化? 一些分类器需要计算样本之间的距离(如欧氏距离),例如KNN。如果一个特征值域范围非常大,那么距离计算就主要取决于这个特征,从而与实际情况相悖(比如这时实际情况是值域范围小的特征更重要)。或者举一个更浅显的例子:对房子进行…

Java——组合总和(3)

题目链接 leetcode在线oj——组合总和&#xff08;3&#xff09; 题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff…

计算机网络 —— TCP篇 TCP 重传、滑动窗口、流量控制、拥塞控制

计算机网络系列文章目录 TCP篇 TCP 重传、滑动窗口、流量控制、拥塞控制 文章目录计算机网络系列文章目录前言4.2 TCP 重传、滑动窗口、流量控制、拥塞控制4.2.1 重传机制超时重传什么情况会触发超时重传超时时间应该设置为多少呢&#xff1f;快速重传SACKD-SACK4.2.2 滑动窗…

【数据结构之二叉树系列】万字深剖数据结构---堆

目录前言一、堆二、堆的实现(重点)1. 数据类型重定义2. 堆结构的定义3. 堆结构的重定义三、堆中常见的基本操作&#xff08;重点&#xff09;1. 声明2. 定义&#xff08;1&#xff09;初始化&#xff08;2&#xff09;销毁&#xff08;3&#xff09;插入数据&#xff08;4&…

macOS Monterey 12.6.3 (21G419) 正式版 ISO、IPSW、PKG 下载

macOS Monterey 12.6&#xff0c;皆为安全更新&#xff0c;不再赘述。 macOS Monterey 12.6&#xff0c;发布于 2022 年 9 月 12 日&#xff08;北京时间今日凌晨&#xff09;&#xff0c;本次为安全更新。 今日&#xff08;2022-07-21&#xff09;凌晨&#xff0c;Apple 终于…

ATAC-seq分析:Peak Calling(8)

1. 寻找开发区域 ATACseq 的一个共同目标是识别转录因子结合和/或转录机制活跃的无核小体区域。该核小体游离信号对应于小于一个核小体的片段&#xff08;如 Greenleaf 论文中定义 < 100bp&#xff09;。 然而&#xff0c;为了识别开放的染色质&#xff0c;我们可以简单地使…

意想不到的结果:Foo(m)可能是在定义名为m的对象

文章目录例一&#xff1a;Foo(m); 是定义名为 m 的对象例二&#xff1a;Foo(m).i; 传入实参 m例三&#xff1a;func(Foo(m)); 传入实参 m例四&#xff1a;S(cout)(1) 定义名为 cout 的对象例五&#xff1a;S(std::cout)(1) 传入实参 std::cout你知道吗&#xff0c;如果 Foo 是…

vue3 watch 监听响应式数据变化

主要是用来监听ref 或者reactive 所包裹的数据才可以被监听到 <template><input type"text" v-model"message"> </template> <script setup lang"ts">import {ref, watch} from "vue";let message ref<s…

powerdesigner画UML组件图初步

组件图 组件图是用来描述组件与组件之间关系的一种UML图&#xff0c;组件图在宏观层面上显示了构成系统某一特定方面的实现结构。 组件图可以用来显示组件之间的依赖关系&#xff0c;以及组件的接口和调用关系。 组件图由组件&#xff0c;接口&#xff0c;组件图中的关系&…