约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。
public class Aa { public static void main(String[] args) { CyclLink cyclink = new CyclLink(); cyclink.setLen(4); cyclink.createLink(); cyclink.setK(1); cyclink.setM(2); cyclink.show(); cyclink.play(); } } /** * 约瑟夫问题, 化为丢手绢 * * @author tianq 思路:建立一个Child类 一个循环列表类CyclLink */ // 先建立一个孩子类 class Child { // 孩子的标识 int no; Child nextChild;// 指向下一个孩子 public Child(int no) { // 构造函数给孩子一个id this.no = no; } } class CyclLink { // 先定义一个指向链表第一个小孩的引用 // 指向第一个小孩的引用,不能动 Child firstChild = null; Child temp = null; int len = 0;// 表示共有几个小孩 int k = 0; //开始的孩子 int m = 0; //数到几推出 // 设置m public void setM(int m) { this.m = m; } // 设置链表的大小 public void setLen(int len) { this.len = len; } // 设置从第几个人开始数数 public void setK(int k) { this.k = k; } // 开始play public void play() { Child temp = this.firstChild; // 1.先找到开始数数的人 for (int i = 1; i < k; i++) { temp = temp.nextChild; } while (this.len != 1) { // 2.数m下 for (int j = 1; j < m; j++) { temp = temp.nextChild; } // 找到要出圈的前一个小孩 Child temp2 = temp; while (temp2.nextChild != temp) { temp2 = temp2.nextChild; } // 3.将数到m的小孩,退出 temp2.nextChild = temp.nextChild; // 让temp指向下一个数数的小孩 temp = temp.nextChild; // this.show(); this.len--; } // 最后一个小孩 System.out.println("最后出圈" + temp.no); } // 初始化环形链表 public void createLink() { for (int i = 1; i <= len; i++) { if (i == 1) { // 创建第一个小孩 Child ch = new Child(i); this.firstChild = ch; this.temp = ch; } else { if (i == len) { // 创建第一个小孩 Child ch = new Child(i); temp.nextChild = ch; temp = ch; temp.nextChild = this.firstChild; } else { // 继续创建小孩 Child ch = new Child(i); temp.nextChild = ch; temp = ch; } } } } // 打印该环形链表 public void show() { Child temp = this.firstChild; do { System.out.print(temp.no + " "); temp = temp.nextChild; } while (temp != this.firstChild); } }
-----------------------------------------------------------------------------------------------------------------
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Aa { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入总人数:"); int totalNum = scanner.nextInt(); System.out.print("请输入报数的大小:"); int cycleNum = scanner.nextInt(); yuesefu(totalNum, cycleNum); } public static void yuesefu(int totalNum, int countNum) { // 初始化人数 List<Integer> start = new ArrayList<Integer>(); for (int i = 1; i <= totalNum; i++) { start.add(i); } //从第K个开始计数 int k = 0; while (start.size() >0) { k = k + countNum; //第m人的索引位置 k = k % (start.size()) - 1; // 判断是否到队尾 if (k < 0) { System.out.println(start.get(start.size()-1)); start.remove(start.size() - 1); k = 0; } else { System.out.println(start.get(k)); start.remove(k); } } } }