import java.util.*;
/**
* 约瑟夫问题java语言实现代码
*
* @author 郁永生
*
*/
// 结点类的定义 每个人都是一个结点
class Node {
int data;// 存放数据
Node nextNode = null;// 下一个结点
// 构造方法
public Node(int data) {
this.data = data;
}
}
// 循环链表类的定义 n个人(n个结点构成一个循环链表)
class CircularList {
int n;// 链表结点数量
private Node firstNode = null;// 第一个人
private Node lastNode = null;// 最后一个人
int k = 1;
int m = 1;
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public int getK() {
return k;
}
public void setK(int k) {
this.k = k;
}
public int getM() {
return m;
}
public void setM(int m) {
this.m = m;
}
public void createCircularList() {
Node tempNode = null;// 游标,标识当前链表最后一个人
for (int i = 1; i <= n; i++) {
if (i == 1) {// 对第一个人初始化
Node node = new Node(i);
firstNode = node;
tempNode = firstNode;// 游标最先指向第一个人
} else {
/*
* if (i != n) { Node node = new Node(i); tempNode.nextNode =
* node;// 末尾新加一个人 tempNode = tempNode.nextNode;//
* 更新tempNode指向新加的人(末尾的人) } else { Node node = new Node(i);
* tempNode.nextNode = node;// 末尾新加一个人 tempNode = node;
* tempNode.nextNode = firstNode;//
* 所有人员加入循环链表后,把最后一个人的下一结点指向第一个人 // 以使链表闭合为循环链表 }
*/
Node node = new Node(i);
tempNode.nextNode = node;// 末尾新加一个人
tempNode = tempNode.nextNode;// 更新tempNode指向新加的人(末尾的人)
}
}
tempNode.nextNode = firstNode;// 所有人员加入循环链表后,把最后一个人的下一结点指向第一个人
// 以使链表闭合为循环链表
lastNode = tempNode;
}
public void Josephu() {
// 找到第K个人
Node tempNode = firstNode;// 游标初始化为第一个人
Node tempPreNode = lastNode;// 游标初始化为最后一个人
for (int i = 1; i < k; i++) {
tempNode = tempNode.nextNode;
tempPreNode = tempPreNode.nextNode;
}// tempNode此时指向第k个人
// 开始报数
while (n!=1) {
for (int j = 1; j <m; j++) {
tempNode = tempNode.nextNode;
tempPreNode = tempPreNode.nextNode;
}
System.out.print(tempNode.data+" ");
// 此时要移除tempNode
// 只需要把tempNode前一个结点指向tempNode后一个结点tempNode.nextNode
// 关键是要找到tempNode前一个结点tempPreNode
tempPreNode.nextNode = tempNode.nextNode;
tempNode = tempNode.nextNode;
n--;
}
System.out.println();
System.out.print(tempNode.data+" 是最后的人 ");
}
// 打印循环链表
public void printCircularList() {
Node tempNode = firstNode;// 游标,标识当前要打印的人
do {
System.out.println("当前人员: " + tempNode.data);
tempNode = tempNode.nextNode;
} while (tempNode != firstNode);
}
}
public class Josephu {
/**
* @param args
*/
public static void main(String[] args) {
int n = 500;
int k = 2;
int m = 2;
CircularList cl = new CircularList();
cl.setN(n);
cl.setK(k);
cl.setM(m);
cl.createCircularList();
//cl.printCircularList();
cl.Josephu();
}
}