约瑟夫问题又名丢手绢问题。相传著名犹太历史学家 Josephus 利用其规则躲过了一场自杀游戏,而后投降了罗马。

问题:

已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。
* 从编号为k的人开始报数,数到m的那个人出列;
* 他的下一个人又从1开始报数,数到m的那个人又出列;
* 依此规律重复下去,直到圆桌周围的人全部出列。 用节点来模拟游戏中的人,用链表来表示游戏中的人按一定的顺序排列。每一个节点给一个编号,从编号为k的节点开始计数,计到m的节点从链表中退出。
之后m的下一个节点从新开始计数,依次...
计数为m的节点要被从链表中删除,只需要将m的上一个节点的引用指向m的下一个节点便可。
依上可知我们的节点类只需要两个属性,一个表示它自己的编号,另一个是引用,指向下一个节点,最后的节点指向第一个节点。
对于第一个节点必须要有一个入口节点————否则无法进入环形链表。

我们需要一个跑龙套的节点以便处理游戏中的计数。
由于是单向链表,所以当我们找到计数为m的节点时还要定位m的上一个节点,并更新其引用,使得计数为m的节点失去引用后被java垃圾回收机制处理掉。
要定义m的上一个节点,可以依链表方向,重新遍历一遍到一个引用指向计数为m的节点,该节点便是。
          还可以将链表换成双向链表,也可以定义两个跑龙套的节点一个用以计数,一个随后以便定位m的上一个节点。
这些方法这里都不用,由于找到计数为m的节点并不需要对它做任何处理,而是处理它的上一个节点————将其引用更新为m的下一个节点,
所以我们可以简而计数到m-1便可直接处理。
给出完整代码如下:
public class JosephCycle {
public static void main(String []args){
CycleLink cl = new CycleLink();
cl.setLen(7);
cl.setK(3);
cl.setM(3);
cl.creatLink();
cl.play();
cl.show();
} } class Node{
int num;
Node nextNode = null;
public Node(int num){
this.num = num;
}
} class CycleLink{
int len;
int k ;
int m ;
Node firstNode = null;
Node temp = null;
public void setLen(int len){
this.len = len;
} public void setK(int k){
this.k = k;
}
public void setM(int m){
this.m =m;
} //创建链表
public void creatLink(){
for(int i = 1; i <= len ; i++){
// 处理首节点
if(i==1){
Node nd= new Node(i);
firstNode = nd;
temp = nd;
}else if(i == len){ //处理末节点
Node nd = new Node(i);
temp.nextNode = nd;
temp = nd;
temp.nextNode = firstNode;
}else{
Node nd = new Node(i);
temp.nextNode = nd;
temp = nd;
}
}
} public void play(){
temp = firstNode;
// 先找到编号为k的节点
for(int i = 1 ; i < k; i++){
temp = temp.nextNode;
}
while(this.len !=1){
//报数,找到m的上一个节点
for(int j = 1 ;j < m-1; j++){
temp = temp.nextNode;
} //因为少报了 1 ,所以将下一个节点删除,并从下下一个节点重新开始报数
System.out.println("要删除的节点: "+temp.nextNode.num);
/**
* 如果删除节点是firstNode,则将firstNode更新为下一个节点
* 注意不能用编号判断,因为新的编号对应的节点有可能又被删除
*/
if(temp.nextNode==firstNode){
firstNode = temp.nextNode.nextNode;
}
temp.nextNode = temp.nextNode.nextNode;
temp = temp.nextNode;
//this.show();
this.len--;
} } /**
* 遍历链表打印整个链表
*/
public void show(){
temp = firstNode;
do{
System.out.println(temp.num);
temp = temp.nextNode;
}while(temp != firstNode);
}
}

这段代码可拿来直接运行,运行结果:

    

最后剩余的节点为:6

在实际应用中,比如排队,根据不同的k,m,len的值,对于有些特殊情况,可能有不同的算法我也不知道,猜测如此!

为何有此猜想,读者可参看:约瑟夫环问题详解

 

java 环形链表实现约瑟夫(Joseph)问题的更多相关文章

  1. PHP算法学习(8) 环形链表 解决约瑟夫问题

    2019年2月25日17:29:17 Josephus有过的故事:39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓.于是决定了自杀方式,41个人排成一个圆圈 ...

  2. php实现单,双向链表,环形链表解决约瑟夫问题

    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn 聊天篇: 数学对我们编程来说,重不重要? 看你站在什么样的层次来说. 如果你应用程序开发,对数学要求 ...

  3. 单向环形链表解决约瑟夫环(Josephus)问题

    一.约瑟夫环问题 Josephu 问题为:设编号为1,2,- n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那 ...

  4. 数据结构与算法——链表 Linked List(单链表、双向链表、单向环形链表-Josephu 问题)

    链表是有序的列表,但是在内存中存储图下图所示 链表是以 节点 的方式来存储,是 链式存储 每个节点包含 data 域.next 域,指向下一个节点 链表的各个节点 不一定是连续存储,如上图所示 链表还 ...

  5. Java数据结构之单向环形链表(解决Josephu约瑟夫环问题)

    1.Josephu(约瑟夫.约瑟夫环)问题: 设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m ...

  6. 3,java数据结构和算法:约瑟夫环出队顺序, 单向环形链表的应用

    什么是约瑟夫环? 就是数小孩游戏: 直接上代码: 要实现这个,只需要理清思路就好了 孩子节点: class Boy{ int no;//当前孩子的编码 Boy next; // 下一节点 public ...

  7. 【java基础 12】HashMap中是如何形成环形链表的?

    导读:经过前面的博客总结,可以知道的是,HashMap是有一个一维数组和一个链表组成,从而得知,在解决冲突问题时,hashmap选择的是链地址法.为什么HashMap会用一个数组这链表组成,当时给出的 ...

  8. 图解Java数据结构之环形链表

    本篇文章介绍数据结构中的环形链表. 介绍 环形链表,类似于单链表,也是一种链式存储结构,环形链表由单链表演化过来.单链表的最后一个结点的链域指向NULL,而环形链表的建立,不要专门的头结点,让最后一个 ...

  9. 丢手帕问题(环形链表)---Java 待优化

    /** * * @author Administrator * 功能:丢手帕问题 */ package com.litao; public class Demo4 { /** * @param arg ...

随机推荐

  1. 8、Spring-Kafka Recving Messages

    Record Listeners The @KafkaListener annotation provides a mechanism for simple POJO listeners. The f ...

  2. Shell 解释器初识

    1.脚本文件要以.sh结尾,第一行要跟#!/bin/bash解释器. 2.运行shell脚本. (1)添加权限:可以加x执行权限,./123.sh (2)命令执行:bash 123.sh,sh 123 ...

  3. Linux firewalld 防火墙

    Linux firewalld 防火墙  简介 RHEL 7 系统中集成了多款防火墙管理工具,其中 firewalld(Dynamic Firewall Manager of Linux system ...

  4. UI自动化(五)dom

    获取标签 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // 直接获取标签   document.getEleme ...

  5. python 的运行方式和基础变量

    机器语言:直接用计算机能听的懂得二进制去编写程序,需要了解硬件细节 优点:执行效率高 缺点:开发效率低汇编语言:用英文单词取代二进制指令去编写程序 优点:开发效率高于机器语言 缺点:执行效率低于机器语 ...

  6. 剑指offer(29)最小的K个数

    题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 题目分析 这题有两种方法来做. 第一种就是基于partition的 ...

  7. jQuery validator plugin之Methods

    step method Makes the element require a given step. step( value ) value Type: Number Step value requ ...

  8. pm2 日常使用

    1. pm2 是什么? 日常开发中需要启动一个node项目,需要用npm run …,,如果终端被关掉,程序也就自动停止,有时候几个项目一起跑起来,好几个终端开着,个人不太喜欢,有一神器可以解决:pm ...

  9. loj#3 -Copycat

    原题链接:https://loj.ac/problem/3 题目描述: --- Copycat 内存限制:256 MiB 时间限制:1000 ms 输入文件: copycat.in 输出文件: cop ...

  10. Kotlin 基础语法

    Kotlin 文件以 .kt 为后缀. 包声明 代码文件的开头一般为包的声明: package com.runoob.main import java.util.* fun test() {} cla ...