1、问题
Josephu(约瑟夫、约瑟夫环) 问题
Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
提示:用一个不带头结点的循环链表来处理Josephu 问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。
2、解决方法
使用环形单向链表来解决
package com.study.linkedlist;public class CircleSingleLinkedList {private Player first = null;public void add(int no){if(no<1){System.out.println("值错误");return;}Player cur = null;for (int i = 1; i <= no; i++) {Player p = new Player(i);if(i==1){first = p;first.next = first;cur = first;}else {cur.next = p;p.next = first;cur = p;}}}public void show(){if(first==null){System.out.println("没有指针");return;}Player cur = first;while (true){System.out.println("指针编号为:"+cur.no);if(cur.next==first){break;}cur = cur.next;}}/**** @param no 表示从第几个节点开始* @param count 表示数几下* @param nums 表示一共有多少个节点*///约瑟夫问题public void count(int no,int count,int nums){if(first==null || no<1 || no>nums){System.out.println("参数有误");return;}Player temp = first;while (true){if (temp.next==first){break;}temp = temp.next;}//先让first和temp移动no-1次for (int i = 0; i < no - 1; i++) {first = first.next;temp = temp.next;}while (true){if(temp==first){System.out.println("最后一个节点为:"+first.no);break;}for (int j=0;j<count-1;j++){first = first.next;temp = temp.next;}System.out.println("出圈的节点为:"+first.no);first = first.next;temp.next = first;}}}
package com.study.linkedlist;
public class CircleSingleLinkedListDemo {
public static void main(String[] args) {
CircleSingleLinkedList csll = new CircleSingleLinkedList();
csll.add(5);
csll.show();
csll.count(1,2,5);
}
}
3、测试结果

