问题表述为:设编号为1,2,...,n的n个人围坐一圈,约定编号为K(1<=k<=n)的人开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依此类推,直到所有人出列为止,由此产生一个出队编号的序列
构建环形队列
package jiegou;
//问题表述为:设编号为1,2,...,n的n个人围坐一圈,
// 约定编号为K(1<=k<=n)的人开始报数,数到m的那个人出列,
// 它的下一位又从1开始报数,数到m的那个人又出列,依此类推,
// 直到所有人出列为止,由此产生一个出队编号的序列
public class JosepfuDemo {
public static void main(String[] args) {
CircleSingleLinkList circleSingleLinkList = new CircleSingleLinkList();
circleSingleLinkList.addBoy(25);
circleSingleLinkList.show();
System.out.println("出圈开始");
circleSingleLinkList.countBoy(1,4,5);
}
}
// 单向环形链表
class CircleSingleLinkList {
// 创建 first 节点
private Boy first = new Boy(-1);
/**
*
* @param startNo 从第几个开始
* @param countNum 数几下
* @param nums 最初多少个
*/
public void countBoy(int startNo,int countNum,int nums)
{
// 数据校验
if(first == null || startNo < 1 || startNo > nums) {
System.out.println("参数输入有误");
return ;
}
// 帮助小孩出圈
Boy helper = first;
// helper 指向尾部停止
while(true){
if(helper.getNext() == first){
break;
}
helper = helper.getNext();
}
//报数前移动到 startNo 位置
for(int j=0;j<startNo-1;j++){
first = first.getNext();
helper = helper.getNext();
}
while(true){
if(helper == first){
break;// 圈中只有一个
}
for (int i = 0; i < countNum-1; i++) {
first = first.getNext();
helper = helper.getNext();
}
// first 指向的就是要出圈的
System.out.printf("小孩%d出圈
",first.getNo());
first = first.getNext();
helper.setNext(first);
}
System.out.printf("最后留在圈中的是%d
",first.getNo());
}
public void addBoy(int nums) {
if (nums <= 0) {
System.out.println("nums参数错误");
return;
}
Boy curBoy = null;
// 使用 for 循环 创建环形链表
for (int i = 1; i <= nums; i++) {
// 根据编号创建小孩节点
Boy boy = new Boy(i);
// 第一个小孩
if (i == 1) {
first = boy;
first.setNext(first);// 构成一个环
curBoy = first;// 让 curboy 指向第一个 boy first 不能动
} else {
curBoy.setNext(boy); //当前小孩链接新的
boy.setNext(first); // 新的链接到头部
curBoy = boy; // 当前指针指向当前这个小孩
}
}
}
public void show() {
if (this.first.getNext() == null) {
System.out.println("链表为空");
return;
}
Boy temp = this.first;
while (true) {
System.out.printf("小孩的编号%d
", temp.getNo());
if (temp.getNext() == first) { // 遍历完毕
break;
}
temp = temp.getNext();
}
}
}
// node
class Boy {
private int no;//编号
private Boy next;// 下一个节点
public Boy(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
@Override
public String toString() {
return "Boy{" +
"no=" + no +
'}';
}
}