java使用链表实现约瑟夫环

Java使用链表实现约瑟夫环

什么是约瑟夫环

约瑟夫环(Josephus problem)是一个有名的问题。传说中,约瑟夫和他的39个朋友圈在一个洞穴中,被罗马军队包围。他们决定集体死了,不肯去做罗马的奴隶。约瑟夫是一个退役士兵,提议从一个人开始,每隔三个人就杀掉一个人。由他开始,最后剩下一个人,他可以叫作胜利。现在问你,应该站在哪个位置,才能够成为那个幸存者?

链表的基本概念

链表是一种常见的数据结构,它由若干个节点(node)组成,每个节点包含两部分:数据域和指针域。其中数据域保存节点的数据,指针域保存下一个节点的地址。链表的头指针指向链表的第一个节点,链表最后一个节点的指针域指向空地址(NULL)。

思路

由于约瑟夫环问题中每个人被杀死后需要从圈中删除,所以我们可以用一个链表表示这个圆圈。第一步,我们先将 $n$ 个人的编号从 $1$ 到 $n$ 建立起来,然后将它们构成一个单向循环链表。

第二步,从第 $k$ 个人开始报数,记为 $m$。然后移动 $m-1$ 个节点,对应的节点即为要删除的节点。删除节点后,重新从当前节点开始报数,直到剩下最后一个节点为止。

Java代码实现

class Node {
    public int value;
    public Node next;

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

public class CircleLinkedList {

    public static Node create(int n) {
        Node head = new Node(1);
        Node p = head;
        for (int i = 2; i <= n; i++) {
            p.next = new Node(i);
            p = p.next;
        }
        p.next = head;
        return head;
    }

    public static void josephus(Node head, int k, int m) {
        Node p = head;
        for (int i = 0; i < k - 1; i++) { // 找到起始节点
            p = p.next;
        }
        while (p.next != p) { // 当链表只有一个节点时结束
            for (int i = 0; i < m - 1; i++) {
                p = p.next;
            }
            System.out.print(p.next.value + " "); // 输出要删除的节点的下一个节点
            p.next = p.next.next; // 删除该节点
        }
        System.out.println("\n剩余节点:" + p.value);
    }

    public static void main(String[] args) {
        int n = 10;
        int k = 3;
        int m = 5;
        Node head = create(n);
        System.out.println("链表中节点的编号依次为: ");
        for (int i = 1; i <= n; i++) {
            System.out.print(head.value + " ");
            head = head.next;
        }
        System.out.println("\n按照约瑟夫环的规则,出列的顺序为:");
        josephus(head, k, m);
    }
}

示例说明

示例一

假设有 $n = 5$ 个人,从第 $k = 1$ 个人开始报数,每报数到 $m = 2$ 个人将删除一个人,输出约瑟夫环的过程如下:

链表中节点的编号依次为: 
1 2 3 4 5 
按照约瑟夫环的规则,出列的顺序为:
2 4 1 5 
剩余节点:3

示例二

假设有 $n = 10$ 个人,从第 $k = 3$ 个人开始报数,每报数到 $m = 4$ 个人将删除一个人,输出约瑟夫环的过程如下:

链表中节点的编号依次为: 
1 2 3 4 5 6 7 8 9 10 
按照约瑟夫环的规则,出列的顺序为:
4 8 2 7 3 10 1 9 6 
剩余节点:5

注意:以上示例中生成链表时编号从 $1$ 到 $n$,要输出约瑟夫环的过程还需要遍历整个链表输出每个节点的编号。实际的应用场景中,可以根据业务需求设计节点的数据域。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java使用链表实现约瑟夫环 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Springboot jar文件如何打包zip在linux环境运行

    这里就为您详细讲解如何将Spring Boot应用打包成Jar文件并在Linux环境中部署运行。 1. 生成Jar包 在使用Maven进行构建的项目中,我们可以使用以下Maven命令将应用程序打包成可执行的Jar文件: mvn clean package 执行该命令后,Maven将会在target目录下生成一个可执行的Jar包,其名称通常为{artifact…

    Java 2023年5月19日
    00
  • Struts和servlet不能共存问题解决方法

    当你在一个Java web项目中同时使用Struts和Servlet时,可能会出现以下错误: java.lang.ClassCastException: org.apache.struts.action.ActionServlet cannot be cast to javax.servlet.Servlet 这是因为Struts包含了一个名为ActionS…

    Java 2023年5月20日
    00
  • java去掉html标签 必须首先去掉双引号的正则

    要去掉html标签,我们可以使用Java的正则表达式来过滤掉带有HTML标记的字符串,即将HTML标记替换为空字符串或其它需要的字符。然而,由于HTML标记中存在引号,我们首先需要过滤掉这些引号,以避免被错误地解析。 以下是要去除HTML标签时可以应用的正则表达式: String regex = "<[^>]+>|&[a-…

    Java 2023年6月15日
    00
  • Spring AOP基本概念

    下面是关于Spring AOP基本概念的完整攻略。 1. 什么是AOP AOP(Aspect-Oriented Programming),即面向切面编程,是OOP(Object-Oriented Programming)的一种扩展。OOP需要在类中定义方法,在方法中编写业务逻辑代码。而AOP则通过预先定义好的切面将所有对象的横切关注点分离出来,然后统一交给切…

    Java 2023年5月19日
    00
  • Java模拟qq软件的详细过程

    我们来详细讲解“Java模拟QQ软件的详细过程”的完整攻略。 1. 项目概述 这个项目的目的是使用Java语言模拟QQ软件的基本功能,包括用户登录、好友管理、信息发送等。整个项目的实现分为三部分: 客户端GUI界面的设计 服务器端的实现 客户端和服务器端之间的通信 2. 客户端GUI界面设计 客户端的GUI界面需要考虑以下几个方面: 登录界面 好友列表界面 …

    Java 2023年6月15日
    00
  • Java8时间接口LocalDateTime详细用法

    Java8时间接口LocalDateTime详细用法 简介 Java8新增了一套时间日期API,称为java.time,提供了更好的可读性和更好的精度。LocalDateTime是这些API的一个实现类,代表了一个本地的日期和时间,不带时区信息。 创建LocalDateTime对象 可以使用now()方法创建当前日期时间的对象: LocalDateTime …

    Java 2023年5月20日
    00
  • Visual Studio Code上添加小程序自动补全插件的操作方法

    操作 Visual Studio Code 上添加小程序自动补全插件的具体步骤如下: 1. 打开 Visual Studio Code 首先,打开你的 Visual Studio Code 编辑器。 2. 打开扩展面板 点击左侧菜单栏最后一个图标,打开 Visual Studio Code 的扩展面板,这里可以搜索并将插件安装到编辑器中。 3. 搜索插件 在…

    Java 2023年5月23日
    00
  • Java实现定时任务

    Java实现定时任务可以使用Java内置的Timer和TimerTask类,也可以使用Spring框架提供的ScheduledExecutorService类。下面分别介绍两种方式的实现方法: 使用Timer和TimerTask类实现定时任务 创建一个Timer对象,并指定它的计划任务和执行时间间隔,例如: Timer timer = new Timer()…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部