什么是约瑟夫问题? 设有编号为1,2,……,n的n(n>0)个人围成一个圈,从第1个人开始报数, 报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数, 报m的出圈,……,如此下去,直到所有人全部出圈为止。当任意给定n和m后,设计算法求n个人出圈的次序。
代码如下:
package com.example.demo.test03;
/**
* 什么是约瑟夫问题
* 设有编号为1,2,……,n的n(n>0)个人围成一个圈,从第1个人开始报数,
* 报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,
* 报m的出圈,……,如此下去,直到所有人全部出圈为止。当任意给定n和m后,设计算法求n个人出圈的次序。
*
* @author 13115
*/
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* 根据约瑟夫问题先自定义一个环形链表
*
* @author 13115
*/
public class Test03 {
public static void main(String[] args) {
CircleLinkedList c = new CircleLinkedList();
c.add(5);
c.showNode();
c.testGame(1, 2, 5);
}
}
/**
* 创建一个环形的单向链表
*/
@Slf4j
class CircleLinkedList {
/**
* 创建第一个节点,没有编号
*/
private Node first = new Node(-1);
/**
* 根据用户输入,计算小孩出圈顺序
* <p>
* no 表示从第几个节点开始数数
* num 便是数几下
* count 表示最初有多少个节点在圈中
*/
public void testGame(int no, int num, int count) {
/**
* 先校验数据
*
*/
if (first == null || no < 1 || no > count) {
System.out.println("输入有误,请重新输入");
return;
}
/**
* 创建辅助指针
*/
Node node = first;
while (true) {
/**
* 如果node的下一个等于第一个 说明只有一个节点
*/
if (node.getNext() == first) {
break;
}
/**
* 让node为first的前一个节点
*/
node = node.getNext();
}
/**
* 遍历出no的位置 起始位置
*/
for (int j = 0; j < no - 1; j++) {
first = first.getNext();
node = node.getNext();
}
while (true) {
/**
*同上条件 如果遍历到最后一个退出循环
*/
if (node == first) {
break;
}
/**
* 遍历出退出节点的位置
*/
for (int j = 0; j < num - 1; j++) {
first = first.getNext();
node = node.getNext();
}
System.out.println(first.getNo() + "节点出来");
/**
* 将节点退出来
*/
first = first.getNext();
node.setNext(first);
}
System.out.println("最后出圈的节点是" + first.getNo());
}
/**
* 添加节点,构建一个环形链表
*/
public void add(int number) {
/**number
* 根据number值创建指定数环形链表
*/
/**
* 首先做一个数据检验
*/
if (number < 1) {
System.out.println("number数值不正确");
log.info("number的数值不能小于1,否则链表无效");
return;
}
/**
* 辅助指针
* 帮助构建环形指针
*/
Node cur = null;
for (int i = 1; i <= number; i++) {
Node node = new Node(i);
/**
* 如果环形为1,让cur指向第一个
*/
if (i == 1) {
first = node;
first.setNext(first);
cur = first;
} else {
cur.setNext(node);
node.setNext(first);
cur = node;
}
}
}
/**
* 遍历环形链表
*/
public void showNode() {
/**
* 因为first还是空,表示没有任何指针加进来
*/
if (first == null) {
System.out.println("没有任何节点");
return;
}
Node node = first;
while (true) {
System.out.println("节点的编号:" + node.getNo());
if (node.getNext() == first) {
return;
} else {
node = node.getNext();
}
}
}
}
/**
* 创建一个类
* 表示一个节点
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
class Node {
/**
* 编号
*/
private int no;
/**
* 指向下一个节点
*/
private Node next;
public Node(int no) {
this.no = no;
}
}