第一种方法
/*
* 约瑟夫问题
* 丢手帕
*/
public class Demo1 {
public static void main(String[] args) {
cycleLink cycleLink=new cycleLink();
cycleLink.setSize(5);
cycleLink.createLink();
cycleLink.showInfo();
cycleLink.setK(2);
cycleLink.setM(2);
cycleLink.play();
}
}
class Child
{
Child nextChild=null;
int num;
public Child(int num)
{
//给小孩一个编号
this.num=num;
}
}
class cycleLink
{
Child firstChild=null;
Child temp=null;
int len=0;//表示共有几个小孩
int k=0;//从第k个小孩开始数数
int m=0;//数m下
public void setM(int m)
{
this.m=m;
}
public void setK(int k)
{
this.k=k;
}
//设置链表大小
public void setSize(int len)
{
this.len=len;
}
//创建一个环形链表
public void createLink()
{
for(int i=1;i<=len;i++)
{
if(i==1)
{
Child ch=new Child(i);
this.firstChild=ch;
temp=ch;
}else if(i==len)
{
Child ch=new Child(i);
temp.nextChild=ch;
temp=ch;
temp.nextChild=this.firstChild;
}else
{
Child ch=new Child(i);
temp.nextChild=ch;
temp=ch;
}
}
}
public void showInfo()
{
Child temp=this.firstChild;
do{
System.out.print(temp.num+" ");
temp=temp.nextChild;
}while(temp!=this.firstChild);
System.out.println();
}
public void play()
{
Child temp1=this.firstChild;
//1.找到开始数数的小孩
for(int i=1;i<k;i++)
{
temp1=temp1.nextChild;
}
while(this.len!=1)
{
//2.数m下
for(int i=1;i<m;i++)
{
temp1=temp1.nextChild;
}
//找到数m的小孩
Child temp2=temp1;
while(temp2.nextChild!=temp1)
{
temp2=temp2.nextChild;
}
//3.将数到m的小孩,踢出圈
temp2.nextChild=temp1.nextChild;
System.out.println("第"+temp1.num+"个小孩出圈了");
//让temp1指向下一个数数的小孩
temp1=temp1.nextChild;
this.len--;
}
System.out.println("最后一个小孩的编号是:"+temp1.num);
}
}
第二种方法
第二种方法没有使用循环遍历去找第m个小孩,而是用temp临时变量纪录第m-1个小孩,让后让该引用指向第m+1个小孩,从而退出第m个小孩,效率明显要高于第一种方法
/*
* 约瑟夫问题
* 丢手帕
*/
package com.test1;
public class Demo7 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
cycleLink cycleLink=new cycleLink();
cycleLink.setSize(5);
cycleLink.createLink();
cycleLink.showInfo();
cycleLink.setK(2);
cycleLink.setM(2);
cycleLink.play();
}
}
class Child
{
Child nextChild=null;
int num;
public Child(int num)
{
//给小孩一个编号
this.num=num;
}
}
class cycleLink
{
Child firstChild=null;
Child temp=null;
int len=0;//表示共有几个小孩
int k=0;//从第k个小孩开始数数
int m=0;//数m下
public void setM(int m)
{
this.m=m;
}
public void setK(int k)
{
this.k=k;
}
//设置链表大小
public void setSize(int len)
{
this.len=len;
}
//创建一个环形链表
public void createLink()
{
for(int i=1;i<=len;i++)
{
if(i==1)
{
Child ch=new Child(i);
this.firstChild=ch;
temp=ch;
}else if(i==len)
{
Child ch=new Child(i);
temp.nextChild=ch;
temp=ch;
temp.nextChild=this.firstChild;
}else
{
Child ch=new Child(i);
temp.nextChild=ch;
temp=ch;
}
}
}
public void showInfo()
{
Child temp=this.firstChild;
do{
System.out.print(temp.num+" ");
temp=temp.nextChild;
}while(temp!=this.firstChild);
System.out.println();
}
public void play()
{
Child temp1=this.firstChild;
//1.找到开始数数的小孩
for(int i=1;i<k;i++)
{
temp1=temp1.nextChild;
}
while(this.len!=1)
{
Child temp2=null;
//2.数m下
for(int i=1;i<m;i++)
{
//找到数m-1的小孩
temp2=temp1;
}
//3.将数到m的小孩,踢出圈
temp2.nextChild=temp1.nextChild;
System.out.println("第"+temp1.num+"个小孩出圈了");
//让temp1指向下一个数数的小孩
temp1=temp1.nextChild;
this.len--;
}
System.out.println("最后一个小孩的编号是:"+temp1.num);
}
}
|
|