Java–单向环形链表
Josepfu(约瑟夫环) 问题
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
解决方案:用一个不带头的循环环形链表来处理Josepfu问题:先构成一个有n个节点的单循环链表,然后由K起点从1开始计数,技术到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从表中删除算法结束。
代码如下:
package com.atguigu;
public class Josepfu {
public static void main(String[] args) {
CircleSingleLinkedList cLinkedList = new CircleSingleLinkedList();
cLinkedList.addBoy(5);
// cLinkedList.listBoy();
cLinkedList.popBoy(1, 2, 5);
}
}
class CircleSingleLinkedList {
// 定义一个标记,表示第一个
private Boy first = null;
// 添加方法
public void addBoy(int nums) {
Boy curBoy = null;// 标记变量
if (nums < 1) {
System.out.println("请输入正确的数据");
return;
}
for (int i = 1; i < nums + 1; i++) {
// 创建小孩
Boy boy = new Boy(i);
if (i == 1) {
first = boy;
boy.setNext(first);
curBoy = first;
} else {
// 将标记变量下个属性标记为添加变量
curBoy.setNext(boy);
boy.setNext(first);
curBoy = boy;
}
}
}
// 遍历
public void listBoy() {
if (first == null) { // 没有数据
System.out.println("没有数据哦,请先添加吧!");
return;
}
Boy curBoy = first;
while (true) {
System.out.println("孩子:" + curBoy.no);
if (curBoy.getNext() == first) {
break;
}
curBoy = curBoy.getNext();
}
}
// 取出孩子
public void popBoy(int startNo, int count, int nums) {
if (first == null || startNo < 1 || startNo > nums || count < 1) {
System.out.println("您输入有误哦,请重新输入");
return;
}
Boy tempBoy = first;
while (true) {
// 初始化tempBoy,将其标记最后一个变量
if (tempBoy.getNext() == first) {
break;
}
tempBoy = tempBoy.getNext();
}
// 移动两个标记到相对位置
for (int i = 1; i < startNo; i++) {
first = first.getNext();
tempBoy = tempBoy.getNext();
}
while (true) {
if (first == tempBoy) {
break;
}
for (int j = 1; j < count; j++) {
first = first.getNext();
tempBoy = tempBoy.getNext();
}
System.out.println("出圈孩子是:" + first.no);
tempBoy.setNext(first.getNext());
first = first.getNext();
}
System.out.println("幸运者是:" + first.no);
}
}
class Boy {
int no;
private Boy next;
public Boy(int i) {
this.no = i;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
}
本文参考尚硅谷韩顺平老师教程