用线性表实现约瑟夫环(java版)

  

约瑟夫环

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

该问题亦称为丢手绢游戏,以下用丢手绢游戏的概念来注释。


用顺序表实现约瑟夫环:

public class linkDemo
{
public static void main(String[] args) {
Link link=new Link();
link.setLen(10);
link.createLink();
link.setStart(2);
link.setDistance(3);
//link.Print();

link.play();
}
}
class  Link{
//先定义一个指向链表第一个小孩的引用 
int len=0; //表示共有几个小孩
int start=0;
int distance=0;
int index=0;
Child[] arr;
public void setLen (int len)
{
this.len=len;

}
public void setStart(int start)
{
this.start=start;
}
public void setDistance(int distance)
{
this.distance=distance;
}
//开始play
public void play()
{ 
index=start-1;
while(this.len!=1)
{
//2.数m下
index=(index+distance-1)%len;
//System.out.println("index:"+index);
System.out.println(Delete(index).no);
}
//输出最后一个小孩
System.out.println(arr[index].no);
}
public void createLink()
{ 
arr=new Child[len];
for(int i=0;i<len;i++)
{ 
arr[i]=new Child(i+1);
}
}
public Child Delete(int i)
{ 

if (len == 0)
throw new RuntimeException( "下溢");
Child  x = arr[i];
for (int j = i; j < len-1; j++)
arr[j] = arr[j+1];
len--;
return x;
}
public void Print()
{
for(int i=0;i<len;i++)
{
System.out.print(arr[i].no+" ");
}
}
}
class  Child
{
int no;
public  Child(int no)
{
//给一个编号
this.no=no;
}
}



用链表实现约瑟夫环:

public class Demo1
{
public static void main(String[] args) {
CycLink cyclink=new CycLink();
cyclink.setLen(10);
cyclink.createLink();
cyclink.setStart(2);
cyclink.setDistance(3);
// cyclink.show();
cyclink.play();
}
}
class  CycLink{
//先定义一个指向链表第一个小孩的引用 
Child firstChild=null;
Child temp=null;
int len=0; //表示共有几个小孩
int start=0;
int distance=0;
public void setLen (int len)
{
this.len=len;

}
public void setStart(int start)
{
this.start=start;
}
public void setDistance(int distance)
{
this.distance=distance;
}
//开始play
public void play()
{ 
Child temp=this.firstChild;
//1.先找到开始报数的人
for(int i=1;i<start;i++)
{
temp=temp.nextChild;

}
while(this.len!=1)
{
//2.数m下 
//找到要出圈的前一个小孩
for(int j=1;j<distance-1;j++)
{
temp=temp.nextChild;
}

System.out.println(temp.nextChild.no);
//3.将数到m的小孩,退出圈。

temp.nextChild=temp.nextChild.nextChild;

//让temp指向下一个小孩
temp=temp.nextChild;

this.len--;
}
//输出最后一个小孩
System.out.println(temp.no);
}
public void createLink()
{
for(int i=1;i<=len;i++)
{
//创建第一个小孩
if(i==1){
Child ch=new Child(i);
this.firstChild=ch;
this.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 show()
{
//定义工作指针
Child temp=this.firstChild;
do{
System.out.println(temp.no);
temp=temp.nextChild;
}while(temp!=this.firstChild);
}
}
class  Child
{
int no;
Child nextChild=null;
public  Child(int no)
{
//编号
this.no=no;
}
}



实验总结和个人想法:

该实验的链表形式代码,参考韩顺平视频中的代码,但在链表的基础上,自行将其改写为顺序表形式代码。通过本实验,我进一步理解到指针在线性表中发挥的作用。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值