Java用单向环形链表来解决约瑟夫环Josepfu问题
作者:叶绿体不忘呼吸 发布时间:2023-03-13 18:54:20
标签:Java,单向环形链表,约瑟夫环,Josepfu
简单介绍
如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点。
单向环形链表应用场景:Josephu(约瑟夫、约瑟夫环)问题:
设编号为1, 2, … n的n个人围坐一圈,约定编号为k (1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
代码实现
节点类
//节点类
class JNode {
private int id;
private JNode next;
public JNode(int id) {
this.id = id;
}
public int getId() {
return id;
}
public JNode getNext() {
return next;
}
public void setNext(JNode next) {
this.next = next;
}
}
链表类(包括节点管理和约瑟夫环问题解决)
//链表类
class CircleSingleLinkedList {
private JNode first = null; //定义第一个节点,未创建时为null
//添加节点,构建环形链表
public void add(int num) {
if (num < 1){
System.out.println("创建个数不符合规定!");
return;
}
JNode curNode = null; //辅助变量
for (int i = 1; i <= num; i++) {
JNode newNode = new JNode(i);
if (i == 1){ //第一个节点较为特殊
first = newNode; //真正创建了第一个节点
first.setNext(first); //形成环状
curNode = first; //让辅助变量开始作用
}else { //第二个及其之后节点
curNode.setNext(newNode); //让当前节点指向新建的节点
newNode.setNext(first); //让新建的节点指向第一个节点,形成环状
curNode = newNode; //更新辅助变量
}
}
}
//遍历链表
public void list(){
if (first == null){
System.out.println("链表为空!");
return;
}
JNode temp = first;
while (true){
System.out.printf("取出节点%d\n",temp.getId());
if (temp.getNext() == first){ //说明已经遍历到最后一个了
break;
}
temp = temp.getNext();
}
}
//根据参数让节点出圈(Josepfu)
public void josepfu(int startNode,int count,int num){ //startNode为开始的那个节点,count为每次数第几个,num为链表节点个数
if (first == null || startNode < 1 || count < 1 || startNode > num){
System.out.println("链表为空或者输入的参数不符合标准!");
return;
}
//让first移动到startNode指定的节点,即移动startNode-1次
for (int i = 0; i < startNode - 1; i++) {
first = first.getNext();
}
//创建一个辅助变量,让其指向最后一个节点(first前一个)
JNode helper = first;
while (helper.getNext() != first){
helper = helper.getNext();
}
//开始按照要求出圈,每次都让helper和first移动count-1次
while (true){
if (helper == first){ //圈中只剩下一个节点
break;
}
for (int i = 0; i < count - 1; i++) {
first = first.getNext();
helper = helper.getNext();
}
//此时first指向的即为要出圈的节点
System.out.printf("节点%d出圈\n",first.getId());
//将出圈的节点从链表中移除
first = first.getNext();
helper.setNext(first);
}
System.out.printf("节点%d为最后一个节点",first.getId());
}
}
测试类
/**
* @Author: Yeman
* @Date: 2021-10-15-22:33
* @Description:
*/
public class JosepfuTest {
public static void main(String[] args) {
CircleSingleLinkedList linkedList = new CircleSingleLinkedList();
linkedList.add(5);
linkedList.list();
System.out.println("===================");
linkedList.josepfu(1,2,5);
}
}
来源:https://blog.csdn.net/m0_46653805/article/details/120791745
0
投稿
猜你喜欢
- step1:先移除centos自带的jdkrpm -qa|grep javarpm -e --nodeps xxstep2:安装jdk (所
- 自动登录是我们在软件开发时一个非常常见的功能,例如我们登录 QQ 邮箱:很多网站我们在登录的时候都会看到类似的选项,毕竟总让用户输入用户名密
- File类简介package com.file;import java.io.File;import java.io.IOException
- Map映射Map映射是一个java集合存储在键 - 值对的元素,并且不允许在列表中重复的元素。 Map接口提供三种collection视图,
- 前言在RocketMQ中为,我们创建消息生产者时,只需要设置NameServer地址,消息就能正确地发送到对应的Broker中,那么Rock
- 一、 测试代码:二、添加参数1、在终端工具中①先编译: javac Test.java②再运行: java Test args1 args2
- 前言本篇内容:提示语的国际化返回,自定义多语言。本文使用aop方式,拦截接口返回的数据,进行转换。正文 先看这次示例教
- 本文实例讲述了JAVA基于数组实现的商品信息查询功能。分享给大家供大家参考,具体如下:综合一维数组和二维数组的相关知识,以及数组排序的多种算
- MultipartResolver和ServletFileUpload冲突如果同时使用了MultipartResolver 和Servlet
- 呐呐呐,做Java呢,最重要是要把自己的“作品” 部署到公网上去啦。特别是初学者,需要向面试官证明自己会什么,这个真的就很重要啦,空口无凭,
- Intellij IDEA 配置Subversion插件实现步骤详解在使用Intellij的过程中,突然发现svn不起效了,在VCS–》Ch
- java 中锁的性能提高办法我们努力为自己的产品所遇到的问题思考解决办法,但在这篇文章中我将给大家分享几种常用的技术,包括分离锁、并行数据结
- 初次接触spring-boot的时候,我们经常会看到这样的文章:“
- 编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观。在软件开发系统中,**“方法的请求者
- 一、关键字关键字:被Java语言赋予特定含义的单词。组成关键字的字母全部小写。注:goto和const作为保留字存在,目前并不使用。main
- IDE的下载和安装:首先,到visual studio官网下载vs2019的安装程序。学生、或个人开发者免费下载第一个community版本
- sftp简介sftp是Secure File Transfer Protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的网络的
- 目前市面上流行的爬虫以python居多,简单了解之后,觉得简单的一些页面的爬虫,主要就是去解析目标页面(html)。那么就在想,java有没
- 本文实例为大家分享了java实现简单石头剪刀布游戏的具体代码,供大家参考,具体内容如下问题描述Alice, Bob和Cindy一起玩猜拳的游
- 1、在Windows下用CMD netstat命令可以获得当前进程监听端口号的信息,如netstat -ano可以看到IP、port、状态和