Java采用循环链表结构求解约瑟夫问题

Java采用循环链表结构求解约瑟夫问题

什么是约瑟夫问题

约瑟夫问题(Josephus problem)是一个著名的趣题,其描述如下:
$n$ 个人围成一圈,从第 $1$ 个人开始报数,报到第 $m$ 个人出圈,然后从出圈的下一个人开始重新报数,重复这个过程,直到圈中只剩下最后一个人,求出这个人的编号。

解决方式

约瑟夫问题的求解方式很多,这里介绍一种使用循环链表结构的方式。主要思路是将 $n$ 个人顺序地组成一个循环链表,每次删除第 $m$ 个人,直至只剩一个人。以下是详细步骤。

  1. 定义节点类
    首先,我们需要定义一个节点类,用于表示每个人。这个节点类应该包含两个属性:编号 $num$ 和指向下一个节点的引用变量 $next$。
public class Node {
    public int num; // 编号
    public Node next; // 下一个节点的引用

    public Node(int num) {
        this.num = num;
    }
}
  1. 构建循环链表
    我们将 $n$ 个人按顺序加入循环链表中,最后一个人的 $next$ 引用指向第一个人,形成一个闭环。
public Node buildCircularList(int n) {
    if (n < 1) {
        throw new IllegalArgumentException("n 必须大于等于 1");
    }
    Node head = new Node(1);
    Node tail = head;
    for (int i = 2; i <= n; i++) {
        Node node = new Node(i);
        tail.next = node;
        tail = node;
    }
    tail.next = head;
    return head;
}
  1. 删除节点
    删除第 $m$ 个节点,可以通过一个循环来实现。每次遍历到第 $m$ 个节点时,删除该节点,并更新上一个节点的 $next$ 引用。
public Node deleteNode(Node head, int m) {
    if (head == null || m < 1) {
        return null;
    }
    int count = 1;
    Node prev = null;
    Node cur = head;
    while (cur.next != cur) {
        if (count == m) {
            // 删除节点
            prev.next = cur.next;
            cur.next = null;
            // 打印删除的节点编号
            System.out.print(cur.num + " ");
            // 移动到下一个节点
            cur = prev.next;
            count = 1;
        } else {
            prev = cur;
            cur = cur.next;
            count++;
        }
    }
    return cur;
}
  1. 示例
    比如,现有 $n=7$ 个人,从第一个人开始报数,数到 $m=3$ 的人出圈。则循环链表构建完成后的样子为:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 1 -> ...

按照删除节点的规则,依次删除第 3、6、2、7、5、1 号节点。直到最后只剩下第 4 号节点。

public static void main(String[] args) {
    int n = 7;
    int m = 3;

    // 构建循环链表
    Node head = new JosephusProblem().buildCircularList(n);

    // 删除节点
    System.out.print("删除节点顺序:");
    Node lastNode = new JosephusProblem().deleteNode(head, m);
    System.out.println("\n剩余节点编号:" + lastNode.num);
}

输出结果为:

删除节点顺序:3 6 2 7 5 1 
剩余节点编号:4

因此,最后留存的节点编号为 4,即第 4 个人。同理,也可以按照此思路求解其他情况下的约瑟夫问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java采用循环链表结构求解约瑟夫问题 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 朋友圈疯传的万能Wi-Fi账号是假的 犯了常识性错误

    朋友圈疯传的万能Wi-Fi账号是假的攻略 背景 近期朋友圈疯传了一个万能Wi-Fi账号和密码:CMCC-EDU,cmcc666666。然而,这个账号并非真实存在的Wi-Fi账号,它是一个虚假信息,而且传播过程中也存在一些常识性错误。以下是一个完整的攻略来揭示这个谣言的真相。 步骤 第一步:查证真相 为了证实这个万能Wi-Fi账号的真假,可以先尝试连接一下这个…

    other 2023年6月27日
    00
  • vue router 配置路由的方法

    Vue Router 配置路由的方法 Vue Router 是 Vue.js 官方的路由管理器,用于实现单页面应用(SPA)的路由功能。下面是配置路由的方法的详细攻略。 步骤一:安装 Vue Router 首先,你需要在你的 Vue.js 项目中安装 Vue Router。可以通过 npm 或者 yarn 进行安装。 npm install vue-rout…

    other 2023年7月28日
    00
  • python-为什么cv2.imwrite()更改图片的颜色?

    当使用cv2.imwrite()函数保存图像时,有时候会发现图像的颜色发生了变化。这种情况可能是由以下原因导致的: 颜色空间不匹配:cv2.imwrite()函数默认使用BGR颜色空间保存图,而其他些库如PIL使用RGB颜色空间。如果您使用cv2.imread()函数读取了一个RGB图像,并使用cv2.imwrite()函数它,则发现图像的颜色发生了变化。解…

    other 2023年5月9日
    00
  • php万字码出完美守护进程详解

    PHP万字码出完美守护进程详解 简介 本攻略的目的是为了帮助 PHP 开发者了解如何实现 PHP 守护进程,主要包括以下内容: 什么是守护进程 为什么需要守护进程 PHP 实现守护进程的方法 守护进程实现注意事项 示例:守护进程监控文件变化 示例:守护进程定时任务 什么是守护进程 守护进程是在后台运行的进程。与其他后台进程不同的是,守护进程在系统启动时就会自…

    other 2023年6月27日
    00
  • Android ndk获取手机内部存储卡的根目录方法

    要在Android NDK中获取手机内部存储卡的根目录,可以使用Java层代码调用Android的API获取路径,再将该路径传递给NDK层。 第一步:在Java层获取存储卡路径 使用以下Java代码可以获取手机内部存储卡的根目录: File storageDir = Environment.getExternalStorageDirectory(); Str…

    other 2023年6月27日
    00
  • Linux平台安装MongoDB及使用Docker安装MongoDB

    Linux平台安装MongoDB及使用Docker安装MongoDB 简介 MongoDB 是一个 NoSQL 数据库,它的灵活性、高效性使其成为互联网数据存储和查询的首选方案。MongoDB 具有良好的数据可扩展性,支持水平和垂直扩展。本文将介绍如何在 Linux 平台上安装 MongoDB 和使用 Docker 安装 MongoDB。 在 Linux 平…

    其他 2023年3月28日
    00
  • jquery-dialog(弹出窗口 遮蔽窗口)

    jquery-dialog(弹出窗口 遮蔽窗口) jQuery是一个流行的JavaScript框架,提供了一系列易于使用的UI组件,其中包括弹出窗口。jQuery弹出窗口不仅易于使用,而且具有高度可定制性,可以使您的网站或应用程序看起来更专业和现代化。 弹出窗口的基本语法 要使用jQuery弹出窗口,您需要引入jQuery库和相关的jQueryUI库。然后,…

    其他 2023年3月28日
    00
  • Spring Boot集成netty实现客户端服务端交互示例详解

    Spring Boot集成Netty实现客户端服务端交互示例详解 介绍 Netty是一个基于Java的专业高性能网络通信框架,其提供了非常优秀的网络通信功能和容易扩展的API。而Spring Boot则是一个具有高度自动化和约定优于配置的约定框架,其简化了Spring的开发流程。通过将两者结合起来,可以更加轻松、方便地实现网络通信的开发。 本文将详细讲解如何…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部