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日

相关文章

  • 如何通过Java监听MySQL数据的变化

    如何通过Java监听MySQL数据的变化? 为了监听MySQL数据的变化,我们可以借助MySQL提供的binlog机制和Java的开源库Canal,来轻松实现对MySQL数据的监听与解析。Canal是阿里巴巴开源的基于binlog的增量订阅&消费组件,用于数据的异构复制和逻辑解析,在大型分布式系统下广泛应用于数据信息同步。 Canal基于阿里中间件团…

    Java 2023年5月20日
    00
  • Spring Boot启动过程(六)之内嵌Tomcat中StandardHost、StandardContext和StandardWrapper的启动教程详解

    Spring Boot是一个基于Spring框架的开源框架,用于快速构建适用于各种应用场景的独立、生产级别的Spring应用程序。在Spring Boot中,内嵌Tomcat作为默认的Servlet容器,为我们提供了灵活的配置和部署方式,本文将详细讲解内嵌Tomcat中StandardHost、StandardContext和StandardWrapper的…

    Java 2023年5月19日
    00
  • Java 生成随机字符的示例代码

    生成随机字符可以使用Java中的Random类和StringBuilder类。Random类是Java中的随机数生成器,StringBuilder类用于构建字符串。 下面是生成随机字符的示例代码: import java.util.Random; public class RandomStringGenerator { private static fina…

    Java 2023年5月27日
    00
  • Spring security认证两类用户代码实例

    下面是详细讲解“Spring security认证两类用户代码实例”的完整攻略。 1. Spring Security认证两类用户 Spring Security可以认证两类用户:前台用户和后台用户。在实际开发中,这两类用户需要分别进行认证,才能保证系统的安全性。 1.1 前台用户 前台用户是指普通用户,通常需要进行注册、登录等操作。Spring Secur…

    Java 2023年5月20日
    00
  • 从源码角度看spring mvc的请求处理过程

    当一个请求到达Spring MVC时,它将会被DispatcherServlet处理,然后将请求转发到相应的Controller中。在控制器中给出响应后,DispatcherServlet再度介入,选择合适的视图并将处理模型渲染到视图上。 下面是从源码角度看Spring MVC请求处理过程的攻略: 概述 Spring MVC负责来自客户端的请求,并通过处理器…

    Java 2023年5月16日
    00
  • Java实现学生成绩输出到磁盘文件的方法详解

    Java实现学生成绩输出到磁盘文件的方法详解 在Java中,实现学生成绩输出到磁盘文件可以分为以下三个步骤: 创建一个磁盘文件对象。 将学生成绩数据写入文件。 关闭文件。 创建一个磁盘文件对象 要创建一个文件对象,在Java中有两种方法:使用File类或Path类。这里以File类为例。 // 引入File类 import java.io.File; // …

    Java 2023年5月27日
    00
  • 超级全面的PHP面试题整理集合第1/2页

    下面是详细的攻略: 第1/2页页面介绍 这是一篇关于PHP面试题的文章,分成1/2页展示,第一页包含了50道PHP面试题,第二页包含了另外50道PHP面试题。对于准备面试的PHP开发人员来说是一份不错的复习资料。该页面的排版清晰简洁,每个问题答案都有详细的解释,更新时间较新,适合PHP初级和高级开发人员进行参考。 页面内容分析 该页面的内容主要由50道PHP…

    Java 2023年6月15日
    00
  • 通过java反射机制动态调用某方法的总结(推荐)

    下面我将为你详细讲解通过 Java 反射机制动态调用某方法的攻略。 什么是 Java 反射机制 Java 反射机制是指在运行时通过 Java 语言特性,可以对类、方法、属性等进行操作的机制。它让 Java 程序在运行时获取某些信息,例如类的全限定名、类的变量和方法等信息,同时也可以在运行时动态地创建和操作对象,例如创建类的实例、调用类的方法、获取和设置类的属…

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