java实现简单的约瑟夫环问题

      我自己学习数据结构的时候,总希望能找到很简单的入门代码,可总是很难找到,于是就想到能写一些简单的java代码。  在百度百科上面搜索到约瑟夫环的问题时,并没有发现java的简单实现,自己在下面弄也是弄了很久,慢慢整理了自己的思路写出了下面的代码。

import java.util.ArrayList;
/*约瑟夫环是一个数学的应用问题:
 * 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。
 * 从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,
 * 数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
      例子
  n = 9, k = 1, m = 5  
 
【解答】   出局人的顺序为5, 1, 7, 4, 3, 6, 9, 2, 8。
*/
public class JOSEPHUS {
 public static void main(String[] args) {
  int n = 9, k = 1, m = 5 ;
  ArrayList<Integer> list=new ArrayList<Integer>(n);
  //初始化一些数据
  for(int i=1;i<=n;i++){
   list.add(i);
  }
  
  int i=k-1,t=1; //初始化下标和计数器
  while(!list.isEmpty()){
   if(t==m){         
     System.out.print(list.remove(i)+"  ");
     i--;//删除过后,i的下标已经变化了,所以需要减少
     t=0;//记数器重新归零
   }
   t++;i++;//往下加
   if(i>=list.size()){//如果到末尾了,就直接跳到开始位置
    i=0;
   }
   }
 }
}
 用ArrayList实现过后,我又思考,能不能直接用数组来写呢?答案是肯定的!呵呵……而且用数组的话,系统的开销一定会比上面用arraylist小得多。下面就是用数组实现的代码了:

public class JOSEPHUS_WITH_ARRAY {
 public static void main(String[] args) {
  int n = 9, k = 1, m = 5;
  int[] list = new int[n];
  // 初始化一些数据
  for (int i = 0; i < n; i++) {
   list[i] = i + 1;
  }

  int i = k - 1, t = 1; // 初始化下标和计数器
  int count = 0;
  boolean isdel = false;
  while (true) {
   if (t == m) {
    System.out.print(list[i % n] + "  ");
    list[i % n] = -1;
    count++;
    isdel = true;/*引入isdel是为了使当list[i]变成-1后不会对后面
     * 判断执行i++还是i++;t++;产生错误的影响*/
    t = 0;// 记数器重新归零
   }
   if (count >= n)//如果都杀完了,就跳循环了,结束程序的执行
    break;
   if (list[i % n] == -1 && !isdel) {
    i++;// 往下加
    isdel = false;
   } else {
    if (list[(i + 1) % n] != -1) {/*这里的判断很关键,这里面其它也包含了一种思想,只考虑两步。如果出现了list[i]=-1同时list[i+1]=-1,那么只是下标移动,而计数器是不能加1的*/
     i++;
     t++;
    } else {
     i++;
    }
   }
  }
 }
}

关于用i%n,即用数组的下标去对数组的长度求余,也是后来才想到的,这样能保证数组永远不会出现越界的情况,而且可以实现类似于循环队列的效果。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值