05--约瑟夫问题【单项环形链表应用】

 

 图形示例:

 

 

 1 //定义Boy类,每一个Boy类的对象都是一个节点
 2 class Boy{
 3     //定义小孩id
 4     private int id; //值域
 5     
 6     //创建构造器初始化值域
 7     public Boy(int id) {
 8         this.id = id;
 9     }
10     
11     private Boy next; //指针域 -->指向下一个节点
12 
13     public int getId() {
14         return id;
15     }
16 
17     public void setId(int id) {
18         this.id = id;
19     }
20 
21     public Boy getNext() {
22         return next;
23     }
24 
25     public void setNext(Boy next) {
26         this.next = next;
27     }
28     
29 }
  1 //定义环形链表类,用于管理生成的节点对象
  2 class CircleSingleLinkedList{
  3     //第一个节点
  4     Boy firstBoy = null;
  5     
  6     //根据传入的数字n,添加n个孩子节点
  7     public void add(int n) {
  8         //参数合法性校验
  9         if (n < 1) {
 10             System.out.println("n为小于1的数字,不合法");
 11             return;
 12         }
 13         //定义辅助指针进行遍历【因为第一个小孩节点不能动】
 14         Boy tmpBoy = null;
 15         for(int i = 1; i <= n; i++) {
 16             Boy boy = new Boy(i);
 17             //特殊情况之只添加一个孩子节点
 18             if (i == 1) {
 19                 firstBoy = boy; //建立链接
 20                 boy.setNext(firstBoy); //构成环
 21                 tmpBoy = firstBoy; //辅助节点赋值
 22             }else {
 23                 tmpBoy.setNext(boy);
 24                 boy.setNext(firstBoy);
 25                 //向后移动,继续遍历添加节点
 26                 tmpBoy = tmpBoy.getNext();
 27             }
 28         }
 29     }
 30     
 31     /**
 32      * @param startBoy  从第几个小孩儿开始数数
 33      * @param eachCount  每次数几个小孩【从当前小孩开始数】
 34      * @param totalBoy 总的小孩的个数
 35      */
 36     public void josephu(int startBoy,int eachCount,int totalBoy) {
 37         //参数合法性校验
 38         //空链表、从第(小于1个)小孩开始、开始的小孩数 > 总的小孩数
 39         if (firstBoy == null || eachCount < 1 || startBoy < 1 || startBoy > totalBoy) {
 40             System.out.println("参数有误");
 41             return;
 42         }else {
 43             //定义辅助指针,指向最后一个小孩
 44             Boy helper = firstBoy;
 45             while(true) {
 46                 //找到了最后要给小孩 --> 指向第一个小孩
 47                 if (helper.getNext() == firstBoy) {
 48                     break;
 49                 }
 50                 //继续往后寻找
 51                 helper = helper.getNext();
 52             }
 53             
 54             //定位到startBoy: 
 55             //firstBoy、helper均移动 eachCount - 1 次
 56             for(int i = 0; i < startBoy - 1; i++) {
 57                 firstBoy = firstBoy.getNext();
 58                 helper = helper.getNext();
 59             }
 60             //循环移动,依次出圈
 61             while(true) {
 62                 //说明就剩最后一个出圈的小孩了
 63                 if (firstBoy == helper) {
 64                     System.out.println(helper.getId()); //等同于 firstBoy.getId()
 65                     helper.setNext(null); //出圈
 66                     break;
 67                 }else {
 68                     //移动到待出圈孩子的位置
 69                     for(int i = 0; i < eachCount - 1; i++) {
 70                         firstBoy = firstBoy.getNext();
 71                         helper = helper.getNext();
 72                     }
 73                     //此时:firstBoy代表的就是要出圈的孩子
 74                     System.out.printf("%d --> ",firstBoy.getId());
 75                     //后移
 76                     firstBoy = firstBoy.getNext();
 77                     helper.setNext(firstBoy);
 78                 }
 79             }
 80         }
 81     }
 82     
 83     //遍历环形单链表
 84     public void list() {
 85         if (firstBoy == null) {
 86             System.out.println("单链表为空");
 87             return;
 88         }else {
 89             //定义辅助节点帮助遍历
 90             Boy tmp = firstBoy;
 91             while(tmp.getNext() != firstBoy) {
 92                 System.out.print(tmp.getId() + " --> ");
 93                 //继续遍历
 94                 tmp = tmp.getNext();
 95             }
 96             //此时临时节点代表第一个孩子节点的上一个节点
 97             System.out.print(tmp.getId());
 98         }
 99     }
100     
101 }
 1 //约瑟夫/环 问题
 2 public class JosephuDemo {
 3 
 4     public static void main(String[] args) {
 5         CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
 6         circleSingleLinkedList.add(5);
 7         circleSingleLinkedList.list();
 8         System.out.println();
 9         System.out.println("约瑟夫问题演示: --> ");
10         circleSingleLinkedList.josephu(1, 2, 5);
11     }
12 
13 }

posted @ 2022-08-10 00:59  羽梦齐飞  阅读(14)  评论(0编辑  收藏  举报