Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >单项环形链表

单项环形链表

原创
作者头像
uglyboy
修改于 2019-12-23 03:24:27
修改于 2019-12-23 03:24:27
52900
代码可运行
举报
运行总次数:0
代码可运行

约瑟夫环问题

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

思路:

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

代码示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Josepfu {
    public static void main(String[] args) {
        SingleCircleLinkedList singleCircleLinkedList = new SingleCircleLinkedList();
        singleCircleLinkedList.Josepfu(1, 2, 5);
    }
}

//创建单项环形链表
class SingleCircleLinkedList {
    //创建一个first节点,当前没有编号
    private Node first;

    /**
     * @param nums 为环形链表添加几个节点
     */
    public void createSingleCircleLinkedList(int nums) {
        if (nums < 1) {
            System.out.println("nums值不正确");
            return;
        }
        Node curNode = null;
        for (int i = 1; i <= nums; i++) {
            //根据编号创建节点
            Node node = new Node(i);
            if (i == 1) {
                first = node;
                first.setNext(first);//构成环
                curNode = first;//让curNode指向第一个节点
            } else {
                curNode.setNext(node);
                node.setNext(first);
                curNode = node;
            }
        }
    }

    /**
     * 遍历当前环形链表
     */
    public void list() {
        if (first == null) {
            throw new RuntimeException("链表为空!");
        }
        Node curNode = first;
        while (true) {
            System.out.println(curNode);
            if (curNode.getNext() == first) {
                break;
            }
            curNode = curNode.getNext();
        }
    }

    /**
     * 根据用户的输入来完成约瑟夫环问题
     *
     * @param startNo  表示从编号几开始数
     * @param countNum 表示数几下
     * @param nums     表示最初有几个人
     */
    public void Josepfu(int startNo, int countNum, int nums) {
        if (nums < 1 || startNo < 1 || startNo > nums) {
            throw new RuntimeException("参数输入有误!");
        }
        createSingleCircleLinkedList(nums);
        Node pre = first;
        //使pre指向first节点的前一个节点
        while (true) {
            if (pre.getNext() == first) {
                break;
            }
            pre = pre.getNext();
        }
        //使first和pre先移动到一开始报数的人那里
        for (int i = 0; i < startNo - 1; i++) {
            first = first.getNext();
            pre = pre.getNext();
        }
        //当第一个人开始报数时,让first和pre指针同时开始移动countNum-1此,然后first指向的节点出圈
        while (true) {
            if (first == pre) {
                break;
            }
            for (int i = 0; i < countNum - 1; i++) {
                first = first.getNext();
                pre = pre.getNext();
            }
            //这时first指向的节点就是要出圈的节点
            System.out.println(first);
            first = first.getNext();
            pre.setNext(first);
        }
        //退出循环后,圈中就只剩下一个节点了。
        System.out.println(first);
    }
}

class Node {
    private int no;

    private Node next;

    public Node(int no) {
        this.no = no;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                '}';
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
图解Java数据结构之环形链表
环形链表,类似于单链表,也是一种链式存储结构,环形链表由单链表演化过来。单链表的最后一个结点的链域指向NULL,而环形链表的建立,不要专门的头结点,让最后一个结点的链域指向链表结点。 简单点说链表首位相连,组成环状数据结构。如下图结构:
wangweijun
2020/02/14
1.9K0
链表
链表
Java架构师必看
2021/04/30
3030
链表
单向环形链表介绍以及约瑟夫问题分析
从判断一个单链表是否存在循环而扩展衍生的问题,有则称之为有环链表问题,也就是经典的约瑟夫问题,也称为约瑟夫环。
周小末天天开心
2023/10/16
2890
单向环形链表介绍以及约瑟夫问题分析
单向环形链表--约瑟夫问题
设编号为1,2,3...,n个人围坐一圈,约定编号为k(1<=k <= n)的人从1开始报数,数到m的那个人出列,紧接着他的下一位又从1开始报数,数到m的那个人又出列,以此类推,直到所有人出列为止,由此产出一个编号的序列
切图仔
2022/09/14
3390
单向环形链表--约瑟夫问题
Qz学算法-数据结构篇(链表、栈)
做add添加时,先找到链表的最后,如果这个链表没有最后,那么我们加入的这个node节点就是这次的头指针指向下一个节点
浅辄
2023/06/07
2160
单向循环链表解决约瑟夫问题
1.什么是约瑟夫问题? 2.约瑟夫问题的解决方式 通过单向循环链表解决,具体思路如下: /** * @author shengjk1 * @date 2020-02-06 */ publ
shengjk1
2020/02/14
5930
作为程序员你真的清楚数据结构吗
数据结构(data structure)是带有结构特性的数据元素的集合,它研究的是数据的逻辑结构和数据的物理结构以及它们之间的相互关系,并对这种结构定义相适应的运算,设计出相应的算法,并确保经过这些运算以后所得到的新结构仍保持原来的结构类型。简而言之,数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合。“结构”就是指数据元素之间存在的关系,分为逻辑结构和存储结构。
苏州程序大白
2022/04/14
3120
作为程序员你真的清楚数据结构吗
Josephu(约瑟夫、约瑟夫环) 问题
Josephu 问题为:设编号为 1,2,… n 的 n 个人围坐一圈,约定编号为 k(1<=k<=n)的人从 1 开始报数,数到 m 的那个人出列,它的下一位又从 1 开始报数,数到 m 的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
乐心湖
2021/01/18
8580
Josephu(约瑟夫、约瑟夫环) 问题
链表
使用带 head头的单向链表实现–水浒英雄排行榜管理完成对英雄人物的增删改查操作,注: 删除和修改 ,查找
用户9615083
2022/12/30
2450
链表
数据结构之链表
使用带head头的单向链表实现 –水浒英雄排行榜管理完成对英雄人物的增删改查操作, 注: 删除和修改
用户11332765
2024/10/28
700
数据结构之链表
看小朋友做游戏顿时解决了约瑟夫问题
Josephu 问题为:设编号为 1,2,… n 的 n 个人围坐一圈,约定编号为 k(1<=k<=n)的人从 1 开始报数,数 到 m 的那个人出列,它的下一位又从 1 开始报数,数到 m 的那个人又出列,依次类推,直到所有人出列为止,由
冷环渊
2021/12/27
3750
看小朋友做游戏顿时解决了约瑟夫问题
java数据结构和算法(一)
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
shaoshaossm
2022/12/26
5820
java数据结构和算法(一)
[数据结构与算法] 邂逅链表
在我们的生活中, 最符合链表结构(准确的说是双链表)的物体的就是火车了(如下图). 我们在车厢内时,每次只能从本车厢到下一个车厢或者上一个车厢,如同对链表的遍历操作一样~~~
时间静止不是简史
2020/07/25
5030
[数据结构与算法] 邂逅链表
约瑟夫问题
1、约瑟夫问题原题: n个小孩子手拉手围成一个圈,编号为k(1 <= k <= n )的人从1开始报数,报到m的那个人出列,它的下一位又从1开始报数,报到m的又出列……依此类推,直到所有人都出列,由此产生一个出队编号的序列。
贪挽懒月
2020/09/08
4880
【Java数据结构和算法】007-链表:循环链表和约瑟夫问题
Josephu  问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列;
訾博ZiBo
2025/01/06
1150
【Java数据结构和算法】007-链表:循环链表和约瑟夫问题
还在为链表而烦恼,看着一篇就够了!
链表是一种 递归 的数据结构,或者为空 null,或者指向一个结点(node)的引用,一个结点含有 一个泛型元素和一个指向另一条链表的引用。
村雨遥
2020/07/14
2530
约瑟夫环的循环链表解法和数学公式解法
约瑟夫环(Josephus)问题是由古罗马的史学家约瑟夫(Josephus)提出的,他参加并记录了公元66—70年犹太人反抗罗马的起义。约瑟夫作为一个将军,设法守住了裘达伯特城达47天之久,在城市沦陷之后,他和40名死硬的将士在附近的一个洞穴中避难。在那里,这些叛乱者表决说“要投降毋宁死”。于是,约瑟夫建议每个人轮流杀死他旁边的人,而这个顺序是由抽签决定的。约瑟夫有预谋地抓到了最后一签,并且,作为洞穴中的两个幸存者之一,他说服了他原先的牺牲品一起投降了罗马。 约瑟夫环问题的具体描述是:设有编号为1,2,……,n的n(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,……,如此下去,直到所有人全部出圈为止。当任意给定n和m后,设计算法求n个人出圈的次序。
海天一树
2018/07/25
2.4K0
链表的常见问题
将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向了这个变量,通过指针就能找到这个变量。
Dlimeng
2023/06/30
1330
java中如何实现单链表反转
以上即是递归实现的源码,但是需要考虑的问题是递归都在java栈中进行,需要考虑jdk支持的栈的深度。在jdk1.8.0_91版本中,当上述链表长度大于12000则会出现StackOverFlowError错误。说明对于该版本jdk栈的深度不能大于12000。
每周聚焦
2025/02/26
1311
java中如何实现单链表反转
单链表LRU算法
链表在初始化时仅需要分配一个元素的存储空间,并且插入和删除新的元素也相当便捷,同时链表在内存分配上可以是不连续的内存,也不需要做任何内存复制和重新分配的操作,由此看来顺序表的缺点在链表中都变成了优势,实际上也是如此,当然链表也有缺点,主要是在访问单个元素的时间开销上。
Dlimeng
2023/06/30
1910
相关推荐
图解Java数据结构之环形链表
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验