约瑟夫问题

    今天用java解决了约瑟夫问题,小结一下。

    问题描述:有n个小孩围成一圈,顺序排号1-n。从编号为k的小孩开始报数,报到m的小孩退出圈子,然后下一个小孩继续从1开始报数,报到m的小孩退出圈子,如此重复。问最后留下的那个小孩的编号是多少?

    例:n=9,k=1,m=5

    依次出列的小孩编号为:5,1,7,4,3,6,9,2。最后留下的小孩编号为8。

附上源代码:

import java.io.*;

/**
 
*@classname Josehu.java
 
*@description 约瑟夫问题
 
*@author 恋风 2010、4、4
 *version 0.1
 *copyright 恋风
 */

 public class Josephus{
 private static Node firstNode;//始终指向第一个节点即首节点,初始化后将不再改变
 private static Node cursorNode;//游标节点,用于建立约瑟夫环和寻找数到devilNumber的节点
 private static int nodeNumber;//节点个数
 private static int startNumber;//开始数数的节点的编号
 private static int devilNumber;//数到devilNumber的节点将出列
 
 /**
  *这是一个节点类,代表约瑟夫环上的一个节点
  */

 protected static class Node{
  private int number;//节点编号
  private Node preNode;//父节点
  private Node nextNode;//子节点
  
  /**
   *构造器
  
*@param nodeNumber 节点编号
   */

  protected Node(int number){
   this.number = number;
  }
 }
 
 public static void main(String[] args){
  //初始化参数
  Josephus.init();
 
  //创建约瑟夫环
  Josephus.createCycle();
  
  //打印约瑟夫环
  System.out.println("小孩顺序编号如下:");
  Josephus.printJosehu();
  System.out.println();
  
  //准备游戏
  System.out.println("准备游戏……");
  Josephus.prePlay();
  
  //开始游戏
  System.out.println("开始游戏啦!");
  Josephus.play();
 }
 
 /**
  *初始化参加游戏的小孩子个数、开始数数的小孩子的编号和魔鬼数字
  */

 private static void init(){
  //创建一个BufferedReader对象,用户读取标准输入的数据
  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  
  try{
   System.out.println("请输入参加游戏的小孩子的个数:");
   String s_nodes = br.readLine();
   Josephus.nodeNumber = Integer.parseInt(s_nodes);
   
   System.out.println("请输入开始数数的小孩的编号(1-"+Josephus.nodeNumber+"):");
   String s_startNumber = br.readLine();
   Josephus.startNumber = Integer.parseInt(s_startNumber);
   
   System.out.println("请输入魔鬼数字(1-"+Josephus.nodeNumber+"):");
   String s_devilNumber = br.readLine();
   Josephus.devilNumber = Integer.parseInt(s_devilNumber);    
  }catch(Exception e){
   System.out.println(e.getMessage());
  }
 }
 
 /**
  *创建约瑟夫环
  */

 private static void createCycle(){
  //创建约瑟夫环
  for(int i = 1;i <= Josephus.nodeNumber;i++){
   if(i == 1){
    //创建首节点
    Node node = new Node(i);
    
    //设置firrstNode和cursorNode都指向首节点
    Josephus.firstNode = node;
    Josephus.cursorNode = node;
   }else{
    if(i == Josephus.nodeNumber){
     //创建尾节点
     Node node = new Node(i);
          
     //设置尾节点的父节点为当前游标节点
     node.preNode = Josephus.cursorNode;
     
     //设置尾节点的nextNode为首节点
     node.nextNode = Josephus.firstNode;
     
     //设置首节点的父节点为尾节点
     Josephus.firstNode.preNode = node;
     
     //设置当前游标节点的nextNode为尾节点node
     Josephus.cursorNode.nextNode = node;
     
     //设置尾节点为当前游标节点
     Josephus.cursorNode = node;
    }else{
     //创建新节点
     Node node = new Node(i);
     
     //设置新节点的父节点为当前游标节点
     node.preNode = Josephus.cursorNode;
     
     //设置当前游标节点的nextNode为新创建的节点node
     Josephus.cursorNode.nextNode = node;
     
     //设置当前新创建的节点node为当前游标节点
     Josephus.cursorNode = node;
    }
   
   }
  }
 }
 
 /**
  *遍历约瑟夫环各节点,输出节点值
  */

 private static void printJosehu(){
  //创建一个Node对象,用于遍历约瑟夫环内的所有节点
  Josephus.cursorNode = Josephus.firstNode;
  
  do{
   System.out.print(Josephus.cursorNode.number+" ");
   Josephus.cursorNode = Josephus.cursorNode.nextNode;
  }while(!Josephus.cursorNode.equals(Josephus.firstNode));
 }
 
 /**
  *寻找开始数数的节点,为游戏做好准备
  */

 private static void prePlay(){
  Josephus.cursorNode = Josephus.firstNode;
  
  //寻找开始数数的节点
  for(int i = 1;i < Josephus.startNumber;i++){
   Josephus.cursorNode = Josephus.cursorNode.nextNode;
  } 
 }
 
 /**
  *开始游戏
  */

 private static void play(){
  //输出游戏最后的剩下那个节点的值
  if(Josephus.cursorNode.nextNode.equals(Josephus.cursorNode)){
   System.out.println("最后剩下的小孩是:"+Josephus.cursorNode.number);
   return;
  }
  
  for(int j = 1;j < Josephus.devilNumber;j++){
   Josephus.cursorNode = Josephus.cursorNode.nextNode;
  }
  //数到devilNumber的节点将出列

  System.out.println("编号为"+Josephus.cursorNode.number+"的小孩出列!");
  Josephus.cursorNode.preNode.nextNode = Josephus.cursorNode.nextNode;
  Josephus.cursorNode.nextNode.preNode = Josephus.cursorNode.preNode;
  
  //从下一个节点开始继续游戏
  Josephus.cursorNode = Josephus.cursorNode.nextNode;
  Josephus.play();
 }
 }

引自:http://user.qzone.qq.com/864717359/infocenter?ptlang=2052

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值