您的位置:首页 > 编程语言 > Java开发

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

2011-10-08 14:45 387 查看
我自己学习数据结构的时候,总希望能找到很简单的入门代码,可总是很难找到,于是就想到能写一些简单的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
;

// 初始化一些数据

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,即用数组的下标去对数组的长度求余,也是后来才想到的,这样能保证数组永远不会出现越界的情况,而且可以实现类似于循环队列的效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息