1、问题

Josephu(约瑟夫、约瑟夫环) 问题
Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
提示:用一个不带头结点的循环链表来处理Josephu 问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。

2、解决方法

使用环形单向链表来解决

  1. package com.study.linkedlist;
  2. public class CircleSingleLinkedList {
  3. private Player first = null;
  4. public void add(int no){
  5. if(no<1){
  6. System.out.println("值错误");
  7. return;
  8. }
  9. Player cur = null;
  10. for (int i = 1; i <= no; i++) {
  11. Player p = new Player(i);
  12. if(i==1){
  13. first = p;
  14. first.next = first;
  15. cur = first;
  16. }else {
  17. cur.next = p;
  18. p.next = first;
  19. cur = p;
  20. }
  21. }
  22. }
  23. public void show(){
  24. if(first==null){
  25. System.out.println("没有指针");
  26. return;
  27. }
  28. Player cur = first;
  29. while (true){
  30. System.out.println("指针编号为:"+cur.no);
  31. if(cur.next==first){
  32. break;
  33. }
  34. cur = cur.next;
  35. }
  36. }
  37. /**
  38. *
  39. * @param no 表示从第几个节点开始
  40. * @param count 表示数几下
  41. * @param nums 表示一共有多少个节点
  42. */
  43. //约瑟夫问题
  44. public void count(int no,int count,int nums){
  45. if(first==null || no<1 || no>nums){
  46. System.out.println("参数有误");
  47. return;
  48. }
  49. Player temp = first;
  50. while (true){
  51. if (temp.next==first){
  52. break;
  53. }
  54. temp = temp.next;
  55. }
  56. //先让first和temp移动no-1次
  57. for (int i = 0; i < no - 1; i++) {
  58. first = first.next;
  59. temp = temp.next;
  60. }
  61. while (true){
  62. if(temp==first){
  63. System.out.println("最后一个节点为:"+first.no);
  64. break;
  65. }
  66. for (int j=0;j<count-1;j++){
  67. first = first.next;
  68. temp = temp.next;
  69. }
  70. System.out.println("出圈的节点为:"+first.no);
  71. first = first.next;
  72. temp.next = first;
  73. }
  74. }
  75. }
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、测试结果

图片.png