Java实现约瑟夫问题

有这样一个问题,有N个人围成一圈做游戏,编号为1->2->3->...->1,让第m个人开始报数,报到底k个数的那个人出队,出队的下一个人继续报数,报到第k个数的人再出队。。。以此类推,求出最后一个出队的人。

    这个问题可以转化成数据结构的循环链表问题。具体抽象为创建循环链表,输出链表,按照题意找到符合要求的那个结点并删除,循环删除的过程,直到循环链表只剩下一个元素,即为最后一个出队的元素。  具体的代码和过程如下:(以n=5,m=2,k=2为例)

public class Demo1 {
public static void main(String[] args){
CycLink link  = new CycLink();
link.setLen(5);
link.creatLink();
link.setM(2);
link.setK(2);
link.show();
link.play();
}
}


class Node{
public int no;
Node nextNode;
public Node(int no){
this.no = no;
}
}


class CycLink{
Node firstNode = null;
Node p = null;
int len=0;
int m; //第m个人
int k;//报k个数
//设置链表大小
public void setLen(int len){
this.len =len;
}
//创建环形链表
public void creatLink(){
for(int i=1;i<=len;i++){
//创建第一个结点
if(i==1){
Node node = new Node(i);
this.firstNode = node;
this.p = node;
}else{
if(i==len){
Node node = new Node(i);
p.nextNode = node;
p=node;
p.nextNode=this.firstNode;
}else{
Node node = new Node(i);
p.nextNode = node;
p = node;
}
}
}
}

//设置第m个人报数 
public void setM(int m){
this.m = m;
}

//设置报几个数
public void setK(int k){
this.k = k;
}

//开始游戏
public void play(){
//找到第m个人
Node temp = this.firstNode;
Node temp2 = this.firstNode;
for(int i=1;i<m;i++){
temp = temp.nextNode;
}
//找到出队的人
for(int j=1;j<k;j++){
temp = temp.nextNode;
}
//出队
while(temp2.nextNode!=temp){
temp2=temp2.nextNode;
}
temp2.nextNode=temp.nextNode;
temp=temp.nextNode;
this.len--;
//输出最后一个出队的人
System.out.println("the last person's number is "+temp.no);
}



//打印循环链表
public void show(){
Node temp = this.firstNode;
do{
System.out.print(temp.no+" ");
temp=temp.nextNode;
}while(temp!=this.firstNode);
}


}


实现的结果截图:


猜你喜欢

转载自blog.csdn.net/qq_34478594/article/details/80351017