约瑟夫环算法(循环链表解决)
问题:约瑟夫环
有编号从1到N的N个人坐成一圈报数,报到M的人出局,下一位再从1开始,
如此持续,直止剩下一位为止,报告此人的编号X。输入N,M,求出X。
(每次递增1个数)
public class Josephus {
public static void main(String[] args) {
System.out.println("Input N and M.");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = s.nextInt();
int point=0,number=1;
List<Integer> list = new ArrayList<Integer>();
for(int i=1;i<=n; i++){
//初始化链表
list.add(i);
}
while(list.size()>1){
if(number%m==0){
System.out.println(list.get(point));
list.remove(point);
--point;
}
++point;//指针后移
++number;
if(point>list.size()-1){
//指针越界重新开始
point=0;
}
}
System.out.println(list.get(0));
}
}
另一种实现方式:(每次递增3个数)
public class Yue {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入总人数:");
int totalNum = scanner.nextInt();
System.out.print("请输入报数的大小:");
int cycleNum = scanner.nextInt();
yuesefu(totalNum, cycleNum);
}
public static void yuesefu(int totalNum, int countNum) {
// 初始化人数
List<Integer> start = new ArrayList<Integer>();
for (int i = 1; i <= totalNum; i++) {
start.add(i);
}
//从第K个开始计数
int k = 0;
while (start.size() >0) {
k = k + countNum;
//k表示在当前链表中第m人的索引位置
k = k % (start.size()) - 1;
// 判断是否到队尾
if (k < 0) {
System.out.println(start.get(start.size()-1));
start.remove(start.size() - 1);
k = 0; //重置索引位置到第一个
} else {
System.out.println(start.get(k));
start.remove(k);
}
}
}
}