Josephu 问题
Josephu 问题为:设编号为 1,2,… n 的 n 个人围坐一圈,约定编号为 k(1<=k<=n)的人从 1 开始报数,数到m 的那个人出列,它的下一位又从 1 开始报数,数到 m 的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
创建一个孩子对象
/**
* 定义一个小孩儿对象
*/
class Boy{
private int no;
private Boy next;
public Boy(int no){
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
}
创建一个循环链表操作对象,有创建环形链表,遍历环形链表,孩子出圈
/**
* 单向循环链表的操作对象
*/
class CircleSingleLinkedList{
Boy first = null;
/**
* 小孩儿出圈
* @param k 从第k个小孩儿开始数
* @param count 数count下出一个小孩儿
* @param nums 小孩儿的个数
*/
public void countBoy(int k,int count,int nums){
if(first == null || k < 1 || k > nums){
System.out.println("参数有误,请重新输入...");
return ;
}
Boy helper = first;
// 1.使helper指针指向最后一个节点
while(true){
if(helper.getNext() == first){
break;
}
helper = helper.getNext();
}
// 2.从第k个小孩儿开始数,所以重置first和helper的位置
for(int j=0;j<k-1;j++){
first = first.getNext();
helper = helper.getNext();
}
// 3.小孩儿出圈
while(true){
// 只剩一个小孩儿了
if(helper == first){
break;
}
// 4.报数时,first和helper指针同时移动count-1次
for(int i=0;i<count-1;i++){
first = first.getNext();
helper = helper.getNext();
}
// 此时,first为要出圈的节点
System.out.println("小孩儿"+first.getNo()+"要出圈");
// 小孩儿出圈
first = first.getNext();
helper.setNext(first);
}
System.out.println("最后出圈的小孩儿为"+first.getNo());
}
/**
* 添加小孩,创建数量为nums的环形链表
* @param nums 小孩的个数
*/
public void addBoys(int nums){
if(nums < 1){
System.out.println("小孩儿的个数不能小于1...");
return;
}
Boy curBoy = null;// 定义一个辅助指针,帮助构建环形链表
// 创建循环链表
for(int i=1;i<=nums;i++){
Boy boy = new Boy(i);
if(i == 1){
first = boy;//
first.setNext(first);// 构成环形链表
curBoy = first;// 让curBoy指向第一个小孩儿
}else{
curBoy.setNext(boy);
boy.setNext(first);
curBoy = boy;
}
}
}
/**
* 遍历小孩儿
*/
public void showBoy(){
Boy curBoy = first;
while(true){
System.out.println("boy"+curBoy.getNo());
if(curBoy.getNext() == first){ // 当最后一个节点指向第一个节点的时候,说明是最后一个节点了
break;
}
curBoy = curBoy.getNext();
}
}
}
测试
/**
* @author AN
* @create 2020-08-27 12:17
*/
public class Josephu {
public static void main(String[] args) {
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addBoys(5);
circleSingleLinkedList.showBoy();
circleSingleLinkedList.countBoy(1,2,5);
}
}
测试结果