约瑟夫环数组java实现_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 list=new ArrayList(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,即用数组的下标去对数组的长度求余,也是后来才想到的,这样能保证数组永远不会出现越界的情况,而且可以实现类似于循环队列的效果。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值