Josephu问题描述
设编号为1,2,…n的m个人围坐一圈,约定编号为n的人从1开始报数,数到k的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
Josephu解决思路
1.构建一个单向的环形链表;
2.需求创建一个辅助指针(变量)helper,事先应该指向环形链表的最后这个节点;
3.将first和helper移动n-1次,找到开始报数位置;
4.在将first和helper移动k-1次,找到需要出圈的位置;
5.将所在位置的节点出圈:
first = first.next
helper.next=first
代码实现
创建对象类
package com.company;
public 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;
}
}
出圈方法
package com.company;
class CircleLinkedList {
private Boy first = null;
public void add(int n){
if(n<1){
System.out.println("the n you want to add isn't right!");
return;
}
Boy curBoy = null;
for(int i=1;i<=n;i++){
Boy boy = new Boy(i);
if(i == 1){
first = boy;
first.setNext(first);
curBoy = first;
}else {
curBoy.setNext(boy);
boy.setNext(first);
curBoy=boy;
}
}
}
public void list(){
if(first==null){
System.out.println("the list is empty");
return;
}
Boy curBoy = first;
while(true){
System.out.printf("the boy's number is:%d\n",curBoy.getNo());
if(curBoy.getNext()==first){
break;
}
curBoy=curBoy.getNext();
}
}
/**
*
* @param n 是开始节点
* @param k 表示数几下
* @param m 表示最初有多少个小孩在圈里
*/
public void countBoy(int n,int k,int m){
if(first==null||k<1||n>m){
System.out.println("Wrong parameter input");
return;
}
Boy temp = first;
while(true){
if(temp.getNext()==first){
break;
}
temp=temp.getNext();
}
for(int i=1;i<n;i++){
temp=temp.getNext();
first=first.getNext();
}
while(true){
if(temp==first){
break;
}
for(int i=1;i<k;i++){
first=first.getNext();
temp=temp.getNext();
}
System.out.println("The boy who is out is:"+first.getNo());
first=first.getNext();
temp.setNext(first);//
}
System.out.println("the winner is"+temp.getNo());
}
}
main方法
package com.company;
public class Main {
public static void main(String[] args) {
// write your code here
CircleLinkedList cl = new CircleLinkedList();
cl.add(5);
cl.list();
cl.countBoy(1,2,5);
}
}
输出结果
the boy’s number is:1
the boy’s number is:2
the boy’s number is:3
the boy’s number is:4
the boy’s number is:5
The boy who is out is:2
The boy who is out is:4
The boy who is out is:1
The boy who is out is:5
the winner is3