-
约瑟夫问题Josephu
问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。单向循环链表
测试方法:
public class Josepfu {
public static void main(String[] args) {
circleSingleLinkedList circleSingleLinkedList=new circleSingleLinkedList();
circleSingleLinkedList.add(150);
// circleSingleLinkedList.showList();
circleSingleLinkedList.out(6,30,150);
}
}
链表的创建、遍历、Josephu实现
class circleSingleLinkedList
{
//定义第一个节点
private Boy first=null;
//构建一个单向的环形链表(不带头节点)
public void add(int nums){//nums表示小孩节点的个数
if(nums<1){
System.out.println("创建失败");
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;//指针变量指向第一个节点
}else{
curBoy.setNext(boy);
boy.setNext(first);
curBoy=boy;//指针指向boy节点
}
}
}
//遍历链表
public void showList(){
if(first==null){
System.out.println("链表为空");
return;
}
Boy curBoy=first;//定义辅助变量
while (true){
System.out.println(curBoy.getNo());
if(curBoy.getNext()==first){ //遍历结束条件
break;
}
curBoy=curBoy.getNext();//指针变量后移
}
}
//小孩出圈的算法
/*
* startNum:要开始的编号
* count:数几下停止
* nums:小孩总数
* */
public void out(int startNum,int count,int nums){
if(first==null||startNum<1||startNum>nums||count>nums){
System.out.println("输入的格式不正常");
return;
}
Boy helper=first;
while (true){ //让helper指针指向最后的节点
if(helper.getNext()==first){
break;
}
helper=helper.getNext();
}
//在报数前,让first和helper变量移动(startNum-1)次
for(int i=0;i<startNum-1;i++){
first=first.getNext();
helper=helper.getNext();
}
//循环,让first和helper指针同时移动count-1次,然后出圈
while (true){
if(helper==first){
break;//最后只剩下一个小孩,helper和first指针指向同一个
}
for(int i=0;i<count-1;i++){
first=first.getNext();
helper=helper.getNext();
}
System.out.println(first.getNo());//出圈的小孩的编号
first=first.getNext();
helper.setNext(first);
}
System.out.println("最后留在圈中的小孩是:"+first.getNo());
}
}
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;
}
}