解题思路:
这道题明显就是一个约瑟夫环的问题,只不过就是简化了,给了一个固定的数而已
思路如下:
1. 需要创建一个单向的循环链表(怎么创建这里我就不多说了)
2. 解决约瑟夫环问题的思路:
2.1 需要创建一个辅助指针(变量)temp,事先应该指向环形链表的最后一个节点
2.2 开始报数前,先让first和temp移动k-1次,也就是先让first指向当前要报数的人,temp指向first的上一个节点。
2.3 当开始报数时,让first和temp同时移动m-1次
2.4 这时就将first指向的节点出圈
2.5 first= first.next
2.6 temp.next = first
2.7 原先first指向的节点就没有任何的引用,就会被垃圾回收机制回收
注意事项:
1. 有链表的基础,懂循环链表
参考代码:
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt();//输入初始人数n ManageCircleNode manageCircleNode = new ManageCircleNode(); manageCircleNode.addNode(n); //manageCircleNode.showList(); manageCircleNode.order(1, 3, n); } //1.首先创建节点 class CircleNode{ private int no;//表示编号 private CircleNode next; public CircleNode(int no) { this.no = no; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public CircleNode getNext() { return next; } public void setNext(CircleNode next) { this.next = next; } } //2.创建节点管理类 class ManageCircleNode{ CircleNode first = null; CircleNode curFomerNode = null;//表示当前节点的指针,用来指向新创建节点的前一个节点 CircleNode curNode = null;//用来指向新创建的节点。 public void addNode(int nums) {//nums:参与的人数 for(int i = 1; i <= nums; i++) { CircleNode newNode = new CircleNode(i); if(i == 1) { //如果是第一个节点,那么first就指向他,之后不能动 first = newNode; //让自己成为一个环 first.setNext(first); curFomerNode = first;//指向第一个节点 } //如果不是第一个,执行以下操作 curFomerNode.setNext(newNode); curNode = newNode; curFomerNode = curNode;//向下移动 curNode.setNext(first);//成为一个环 } } //求出圈的顺序 /** * * @param k 表示从编号k个人开始数 * @param m 表示数到m号(及是m号的人出列) * @param nums */ public void order(int k,int m,int nums) { //首先先让一个辅助变量指向first的最后一个节点,也就是first的上一个节点 CircleNode temp = first; while(true) { if(temp.getNext() == first) { break; } temp = temp.getNext(); } //在开始报数之前,先将temp和first移动k-1次 for(int i = 1; i <= k-1 ; i++) { temp = temp.getNext(); first = first.getNext(); } //开始报数时,让first和temp同时移动m-1次,然后出圈 while(true) { if(temp == first) { //此时圈中只有一个节点,出圈 break; } for(int i = 1; i <= m-1; i++) {//first指的节点就是要出圈的 temp = temp.getNext(); first = first.getNext(); } //System.out.printf("编号为%d的人出圈\n",first.getNo()); first = first.getNext();//指向下一个 temp.setNext(first); } System.out.println(temp.getNo());//最后一个出圈的是编号的节点 } //测试方法:遍历单向循环链表 public void showList() { if(first == null) { System.out.println("链表为空~~~"); return; } //遍历节点;当遇到curFormerNode.getNext() == first时结束 curFomerNode = first;//指向第一个节点 while(true) { System.out.println("圈中的编号为:"+curFomerNode.getNo()); if(curFomerNode.getNext() == first) { break; } curFomerNode = curFomerNode.getNext(); } } }
0.0分
0 人评分
sizeof的大作用 (C语言代码)浏览:1592 |
C语言程序设计教程(第三版)课后习题1.5 (C语言代码)浏览:645 |
1014题解浏览:524 |
简单的a+b (C语言代码)浏览:572 |
C语言程序设计教程(第三版)课后习题8.9 (C语言代码)浏览:576 |
简单的a+b (C语言代码)浏览:672 |
1073题解浏览:652 |
用getchar()函数接收字符,正序输入为什么会倒序输出浏览:767 |
C语言程序设计教程(第三版)课后习题8.3 (C语言代码)(标记法)浏览:709 |
字符串比较 (C语言代码)浏览:1261 |