用java实现约瑟夫环问题

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。

1.用单链表实现

package com.cws.joseph;
import java.util.Date;
public class JosephCircle {
 /**
  * 作者: 
  * 功能:约瑟夫环
  * 用单链表实现
  */
 public static void main(String[] args){
  NodeLink link = new NodeLink();
 // link.setLen(5);
   System.out.println("开始创建"+new Date());
  link.createLink(1000000);
   System.out.println("创建结束"+new Date());
 // link.test();
     link.setK(1000);
     link.setM(1000);
     System.out.println("开始游戏"+new Date());
     link.play();
     System.out.println("游戏结束"+new Date());
  
 }
}

class Node{
 private long no;
 private Node nextNode;
 public long getNo() {
  return no;
 }
 public void setNo(long no) {
  this.no = no;
 }
 public Node getNextNode() {
  return nextNode;
 }
 public void setNextNode(Node nextNode) {
  this.nextNode = nextNode;
 }
 public Node(long no){
  this.no=no;
 }
  
}

class NodeLink{
 private Node firstNode;
 private Node temp;
 private Node temp2;
 private long len;
 private long k;//第几个人开始报数
 private long m;//每次报多少数
 
 
 public Node getTemp2() {
  return temp2;
 }
 public void setTemp2(Node temp2) {
  this.temp2 = temp2;
 }
 public long getK() {
  return k;
 }
 public void setK(long k) {
  this.k = k;
 }
 public long getM() {
  return m;
 }
 public void setM(long m) {
  this.m = m;
 }
 public void createLink(long len){
  this.len = len;
  for(long i = 1;i<=len;i++){
   if(i==1){
    Node node = new Node(i);
    firstNode = node;
    temp = node;
   }else if(i != 1 && i != len){
    Node node = new Node(i);
    temp.setNextNode(node);
    temp = node;
   }else{
    Node node = new Node(i);
    temp.setNextNode(node);
    temp = node;
    temp.setNextNode(firstNode);
    
   }
  }
  
 }
 
 public void test(){
  for(long i =0;i<this.len;i++){
   if(i==0){
    temp=firstNode;
   }
   System.out.println(temp.getNo());
   temp = temp.getNextNode();
  }
 }
 
 public void play(){
  temp = firstNode;
  //先找到第一个报数的人
  for(long i = 1;i<k;i++){
   temp = temp.getNextNode();
  }
  while(this.len != 1){
   //找到要出列的人
   for(long i=1;i<m;i++){
    if(i==(m-1)){
     temp2 = temp;
    }
    temp = temp.getNextNode();
   }
   
   //让要出列的人出列
   temp2.setNextNode(temp.getNextNode());
   temp = temp.getNextNode();
   this.len--;
   
  }
 
  System.out.println("最后一个出列的是"+temp.getNo());
  
 }
 
 
 
 
 public Node getFirstNode() {
  return firstNode;
 }
 public void setFirstNode(Node firstNode) {
  this.firstNode = firstNode;
 }
 public Node getTemp() {
  return temp;
 }
 public void setTemp(Node temp) {
  this.temp = temp;
 }
 public long getLen() {
  return len;
 }
 public void setLen(long len) {
  this.len = len;
 }
 
}

2.用双链表解决

package com.cws.joseph;
import java.util.Date;
public class JosephCircle_2 {
 /**
  * 作者:
  * 功能:约瑟夫环
  * 用双向链表实现
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  DoubleLink doubleLink = new DoubleLink();
   System.out.println("开始创建"+new Date());
  doubleLink.createDoubleLink(1000000);
   System.out.println("创建结束"+new Date());
 // doubleLink.testlast();
  doubleLink.setK(1000);
  doubleLink.setM(1000);
  System.out.println("开始游戏"+new Date());
  doubleLink.play();
  System.out.println("游戏结束"+new Date());
 }
 
}
class DoubleNode{
 private long no;
 private DoubleNode lastNode;
 private DoubleNode nextNode;
 public long getNo() {
  return no;
 }
 public void setNo(long no) {
  this.no = no;
 }
 public DoubleNode getLastNode() {
  return lastNode;
 }
 public void setLastNode(DoubleNode lastNode) {
  this.lastNode = lastNode;
 }
 public DoubleNode getNextNode() {
  return nextNode;
 }
 public void setNextNode(DoubleNode nextNode) {
  this.nextNode = nextNode;
 }
 public DoubleNode(long no){
  this.no = no;
 }
}
class DoubleLink{
 private long len;
 private DoubleNode firstNode;
 private DoubleNode lastNode;
 private DoubleNode temp;
 private DoubleNode temp2;
 private long k;//第几个人开始报数
 public long getK() {
  return k;
 }
 public void setK(long k) {
  this.k = k;
 }
 public long getM() {
  return m;
 }
 public void setM(long m) {
  this.m = m;
 }

 private long m;//每次报多少数
 public long getLen() {
  return len;
 }
 public void setLen(long len) {
  this.len = len;
 }
 public DoubleNode getFirstNode() {
  return firstNode;
 }
 public void setFirstNode(DoubleNode firstNode) {
  this.firstNode = firstNode;
 }
 
 public void createDoubleLink(long len){
  this.len = len;
  for(long i=1;i<=len;i++){
   if(i == 1){
    DoubleNode doubleNode = new DoubleNode(i);
    firstNode = doubleNode;
    temp = doubleNode;
    temp2 = doubleNode;
   }else if(i !=1 && i !=len){
    DoubleNode doubleNode = new DoubleNode(i);
    temp.setNextNode(doubleNode);//设置上个的下一个
    temp = doubleNode;//移动到当前
    temp.setLastNode(temp2);//设置当前个的上一个
    temp2 = doubleNode;
   }else{
    DoubleNode doubleNode = new DoubleNode(i);
    lastNode = doubleNode;
    temp.setNextNode(doubleNode);//设置上个的下一个
    temp = doubleNode;//移动到当前
    temp.setLastNode(temp2);//设置当前个的上一个
    temp.setNextNode(firstNode);//设置最后一个的下一个为第一个
    temp=firstNode;//移动到第一个
    temp.setLastNode(doubleNode);//设置第一个的上一个为最后一个
   }
  }
 }
 
 public void play(){
  temp = firstNode;
  //先找到第一个报数的人
  for(long i = 1;i<k;i++){
   temp = temp.getNextNode();
  }
  while(this.len != 1){
   //找到要出列的人
   for(long i=1;i<m;i++){
    temp = temp.getNextNode();
   }
   
   //让要出列的人出列
  // temp2.setNextNode(temp.getNextNode());
   if(len != 2){
    temp2 = temp.getLastNode();
    temp = temp.getNextNode();
    temp2.setNextNode(temp);
    temp.setLastNode(temp2);
   }else{
    temp = temp.getNextNode();
    temp.setLastNode(null);
    temp.setNextNode(null);
   }
   
   this.len--;
   
  }
 
  System.out.println("最后一个出列的是"+temp.getNo());
  
 }
 
 
 public void testnext(){
  for(long i =0;i<this.len;i++){
   if(i==0){
    temp=firstNode;
   }
   System.out.println(temp.getNo());
   temp = temp.getNextNode();
  }
 }
 
 
 public void testlast(){
  for(long i=this.len;i>=1;i--){
   if(i == this.len){
    temp = lastNode;
    
   }
   System.out.println(temp.getNo());
   temp = temp.getLastNode();
  }
  
 }
 
 
}

转载于:https://my.oschina.net/u/2009964/blog/352333

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值