约瑟夫问题
概述:
一共有n个人围成一圈,事先给定两个值k,m,其中k代表一开始从第k个人开始数1,m代表数到m的人出圈,每次出圈一个人,从出圈的那个人的下一个人继续从1开始数,数到m的人再出圈,如此循环,直到最后一个人留在圈里,这样我们就可以得到一个按出圈顺序排列的数的序列。
根据这样的问题,我们利用java来编程实现:
主要思想:
1、创建一个小孩类,其拥有自身的元素值,又能够指向下一个小孩
2、创建一个环形链表代表一个圈,每次出圈一个小孩,就将其上一个小孩的nextchild指向其下一个小孩,这样就相当于出圈了,即从环形链表中删除
3、出圈的动作是一直进行的,直到剩下最后一个小孩,我们需要设置环形链表的长度len,即开始游戏之前一共有多少个小孩参加游戏,每次出圈len减一
/**
* Author:MrBread
* Function:解决约瑟夫问题
* Date:2017-03-29
*/
package com.mycode.test;
public class Joseph {
public static void main(String []args){
CycleLink cl=new CycleLink(); //创建环形链表对象
cl.setLen(10); //设置环形链表的长度
cl.create(); //初始化环形链表
cl.setK(2); //设置k
cl.setM(2); //设置m
cl.play(); //开始游戏
}
}
//定义一个小孩类
class Child{
int num;
Child nextchild;
//构造函数设置小孩中的num值
public Child(int num){
this.num=num;
}
public Child(){}
}
//定义一个环形链表
class CycleLink{
Child firstchild;//定义环形链表的头节点
Child temp;
int k=0; //k代表从第几个小孩开始数
int m=0; //m代表数到几就出圈
int len=0; //代表环形链表中小孩的总数
//设置环形链表的长度
public void setLen(int len){
this.len=len;
}
//构造设置k值的方法
public void setK(int k){
this.k=k;
}
//构造设置m值的方法
public void setM(int m){
this.m=m;
}
//初始化环形链表,即根据len大小创建具体的小孩
public void create(){
for(int i=1;i<=len;i++){
if(i==1){
Child ch=new Child(i);
temp=ch;
firstchild=ch;
}else if(i>1&&i<len){
Child ch=new Child(i);
temp.nextchild=ch;
temp=temp.nextchild;
}else{
Child ch=new Child(i);
temp.nextchild=ch;
temp=temp.nextchild;
temp.nextchild=firstchild;
}
}
}
//开始丢手帕游戏,最后按出圈的顺序输出一串数
public void play(){
//遍历环形链表找出第k个人
temp=firstchild;
for(int i=1;i<k;i++){
temp=temp.nextchild;
}
//跳出循环之后就知道temp指向了开始报数的那个小孩
while(this.len!=1) //一直循环,直到剩下最后一个小孩
{
//从temp指向的那个小孩开始报1,遍历链表找到数m的那个小孩
for(int j=1;j<m;j++)
{
temp=temp.nextchild;
}
//循环结束之后我们就知道temp指向了要出圈的那个小孩
//打印要出圈小孩的num值
System.out.println(temp.num);
//将那个要出圈的小孩请出圈,即删除该小孩
Child temp2=new Child();
temp2=firstchild;
for(int i=1;i<=len;i++){
if(temp2.nextchild==temp){ //若temp2指向的是要删除小孩的上一个小孩,则跳出循环
break;
}
temp2=temp2.nextchild;
}
temp2.nextchild=temp.nextchild;//完成删除操作
//让下一个小孩重新从1开始报数
temp=temp.nextchild;
this.len--;//每次请出圈就把链表长度减一
}
//打印最后一个小孩的num值
System.out.println(temp.num);
}
}
测试结果如图: