约瑟夫问题
Posted -xuewuzhijing-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了约瑟夫问题相关的知识,希望对你有一定的参考价值。
约瑟夫问题:N个人围成一圈,从约定编号为K的人开始报数,第M个将被杀掉,依次类推,最后剩下一个,其余人都将被杀掉。
直接上图展示,初始化状态: 假设n=6,总共有6个人,k=1,从第一个人开始报数,m=5,每次数五个。
1 package linkedlist; 2 3 public class josepfu { 4 5 public static void main(String[] args) { 6 //构建环形链表 7 CirclesingleLinkedList circlesingleLinkedList = new CirclesingleLinkedList(); 8 circlesingleLinkedList.addBoy(5); 9 circlesingleLinkedList.showBoy(); 10 circlesingleLinkedList.countBoy(1, 2, 5); 11 } 12 13 } 14 15 //创建环形单向链表 16 class CirclesingleLinkedList { 17 private Boy first = new Boy(-1); 18 19 public void addBoy(int nums) { 20 if (nums < 1) { 21 System.out.println("nums的值不正确"); 22 return; 23 } 24 Boy curBoy = null; 25 for (int i = 1; i <= nums; i++) { 26 Boy boy = new Boy(i); 27 if (i == 1) { 28 first = boy; 29 first.setNext(first); 30 curBoy = first; 31 } else { 32 curBoy.setNext(boy); 33 boy.setNext(first); 34 curBoy = boy; 35 } 36 } 37 } 38 39 // 遍历当前环形链表 40 public void showBoy() { 41 if (first == null) { 42 System.out.println("没有任何小孩"); 43 return; 44 } 45 Boy curBoy = first; 46 while (true) { 47 System.out.println("小孩的编号" + curBoy.getNo()); 48 if (curBoy.getNext() == first) { 49 break; 50 } 51 curBoy = curBoy.getNext(); 52 53 } 54 } 55 56 // 根据用户的输入,计算小孩出圈的顺序 57 /** 58 * 59 * @param startNo表示从第几个小孩开始数数 60 * @param counntNum表示数几下 61 * @param nums表示最初有多少小孩在圈中 62 */ 63 public void countBoy(int startNo, int countNum, int nums) { 64 // 先对数据校验 65 if (first == null || startNo < 1 || startNo > nums) { 66 System.out.println("参数有误"); 67 } 68 Boy helper = first; 69 // helper指向环形链表的最后节点 70 while (true) { 71 if (helper.getNext() == first) { 72 break; 73 } 74 helper = helper.getNext(); 75 } 76 // 小孩报数前,先让first和helper移动k-1次 77 for (int j = 0; j < startNo - 1; j++) { 78 first = first.getNext(); 79 helper = helper.getNext(); 80 } 81 // 让first和helper指针同时移动m-1次,然后出圈 82 while (true) { 83 if (helper == first) {// 圈中只有一个 84 break; 85 86 } 87 // 让first和helper指针同时移动countNum-1 88 for (int j = 0; j < countNum - 1; j++) { 89 first = first.getNext(); 90 helper = helper.getNext(); 91 } 92 // 这时first指向的节点,就是要出圈的小孩节点 93 System.out.println("小孩" + first.getNo() + "出圈"); 94 first = first.getNext(); 95 helper.setNext(first); 96 } 97 System.out.println("留在圈中的小孩编号" + first.getNo()); 98 } 99 100 } 101 102 class Boy { 103 private int no; 104 private Boy next; 105 106 public Boy(int no) { 107 super(); 108 this.no = no; 109 } 110 111 public int getNo() { 112 return no; 113 } 114 115 public void setNo(int no) { 116 this.no = no; 117 } 118 119 public Boy getNext() { 120 return next; 121 } 122 123 public void setNext(Boy next) { 124 this.next = next; 125 }; 126 127 }
以上是关于约瑟夫问题的主要内容,如果未能解决你的问题,请参考以下文章