Java Joseph 问题:
Joseph 问题为:设编号为1,2,3......n 的 n 个人围坐一起,约定编号为 k (1<=k<=n) 的人从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,以此类推,知道所有的人出列为止,由此产生一个出队编号的序列。
提示:
用一个不带头结点的循环链表来处理 Joseph 问题:先构成一个有 n 个结点的单循环链表,然后由k结点从1开始计数,计数到m,对应的结点从链表中删除,然后再从被删除结点的下一个结点由从1开始计数,知道最后一个结点从链表中删除,算法结束。
解题思路:
整体代码:
/*
* 项目名称:ANA
* 文件名称:CircleSingleLickedListDemo.java
* Date:2023/9/25 上午11:00
* Author:yan_Bingo
*/
package Learning;
/**
* @author Yan_Bingo
* @version 1.0
* Create by 2023/9/25 11:00
*/
public class CircleSingleLickedListDemo {
public static void main(String[] args) {
CircleSingleLickedList circleSingleLickedList = new CircleSingleLickedList();
circleSingleLickedList.addBoy(5);
System.out.println("输出循环链表的情况");
circleSingleLickedList.showCircleList();
System.out.println();
circleSingleLickedList.countBoy(1, 2, 5);
}
}
class CircleSingleLickedList{
private Boy first = null;
// 指定添加 nums 个小孩
public void addBoy(int nums){
// 如果输入要添加的数量小于1,直接返回
if(nums < 1){
System.out.println("输入的数量小于1");
return;
}
Boy curBoy = null; // 设置一个中间中间变量记录当前循环链表的最后一个
for (int i = 1; i <= nums ; i++) {
Boy boy = new Boy(i);
if(i == 1){
first = boy;
first.setNext(first);
curBoy = first;
}else{
curBoy.setNext(boy);
boy.setNext(first);
curBoy = boy;
}
}
}
// 输出链表的情况
public void showCircleList(){
if(first == null){
System.out.println("当前的链表为空,无法查询~~~");
}
Boy curBoy = first;
while (true){
System.out.println(curBoy);
if(curBoy.getNext() == first){
break;
}
curBoy = curBoy.getNext();
}
}
/**
*
* @param startNo 表示从第几个小孩开始
* @param k 表示小孩数几下出圈
* @param nums 表示一共有多少个小孩
*/
// 输入小孩出圈的顺序
public void countBoy(int startNo, int k, int nums){
if(startNo < 1 || k < 1 || nums < 1 || first == null || startNo > nums){
System.out.println("输入的参数有误,请重新输入");
return;
}
Boy helper = first;
while (true){
if(helper.getNext() == first){
// 说明这时 helper 的下一位就是first 即 最后一个小孩的位置
break;
}
helper = helper.getNext();
}
// 将 first 和 helper 移动到 第 startNo 个和第 startNo-1 的位置
for (int i = 0; i < startNo-1 ; i++) {
first = first.getNext();
helper = helper.getNext();
}
for (int i = 1; i < nums ; i++) {
if(helper == first){
break;
}
for (int j = 1; j < k; j++) {
first = first.getNext();
helper = helper.getNext();
}
System.out.printf("编号为%d的小孩出圈了\n", first.val);
first = first.getNext();
helper.setNext(first);
}
// 输入最后一个小孩出圈
System.out.printf("编号为%d的小孩出圈了", first.val);
}
}
class Boy{
public int val;
public Boy next;
public Boy(int val) {
this.val = val;
}
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
@Override
public String toString() {
return "Boy{" +
"val=" + val +
'}';
}
}