- 创建单向的环形链表
(1)创建第一个结点,并设置first指针指向该结点,并使得该点的next指向first,构成环形链表
(2)后面每创建一个结点,就将该结点按上述方式加入环形链表
public void addChild(int nums) {
if(nums < 1) {
System.out.println("输入数值不正确,请重新输入~~");
return;
}
Child curChild = null;
for(int i = 1; i <= nums; i++) {
Child child = new Child(i);
if(i == 1) {
first = child;
first.next = first;
curChild = first;
}else {
curChild.next = child;
child.next = first;
curChild = child;
}
}
}
- 遍历环形链表
(1)创建辅助指针(curChild)指向first结点
(2)通过while循环遍历环形链表,直到curChild.next == first时结束循环
public void show() {
if(first == null) {
System.out.println("环形链表为空~~~");
return;
}
Child curChild = first;
while(true) {
System.out.printf("小孩的编号为%d\n", curChild.no);
if(curChild.next == first) {
break;
}
curChild = curChild.next;
}
}
3.约瑟夫环思路
(1)创建一个辅助指针helper(设从编号为startNo的孩子开始报数,当报数为countNum时删除该孩子,范围为到编号为nums的孩子)
指向环形链表的最后
(2)将first和helper移动startNo-1次
(3)报数时,将first和helper移动countNum-1次
(4)first指向的孩子出圈 first = first.next helper.next = first
public void countChildren(int startNo, int countNum, int nums) {
//对数据进行校验
if(first == null || startNo < 1|| startNo > nums) {
System.out.println("参数输入有误,请重新输入~~");
return;
}
Child helper = first;
while(true) {
if(helper.next == first) {
break;
}
helper = helper.next;
}
for(int j = 0; j <startNo - 1; j++) {
first = first.next;
helper = helper.next;
}
while(true) {
if(helper == first) {
break;
}
for(int j = 0; j < countNum - 1; j++) {
first = first.next;
helper = helper.next;
}
System.out.printf("小孩%d出圈\n", first.no);
first = first.next;
helper.next = first;
}
System.out.printf("最后留在圈中的小孩的编号为%d\n", first.no);
}
整体代码如下
package com.replay.linkedList;
public class Josepfu {
public static void main(String[] args) {
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addChild(5);
circleSingleLinkedList.show();
circleSingleLinkedList.countChildren(1, 2, 5);
}
}
class CircleSingleLinkedList{
private Child first = null;
public void addChild(int nums) {
if(nums < 1) {
System.out.println("输入数值不正确,请重新输入~~");
return;
}
Child curChild = null;
for(int i = 1; i <= nums; i++) {
Child child = new Child(i);
if(i == 1) {
first = child;
first.next = first;
curChild = first;
}else {
curChild.next = child;
child.next = first;
curChild = child;
}
}
}
public void show() {
if(first == null) {
System.out.println("环形链表为空~~~");
return;
}
Child curChild = first;
while(true) {
System.out.printf("小孩的编号为%d\n", curChild.no);
if(curChild.next == first) {
break;
}
curChild = curChild.next;
}
}
public void countChildren(int startNo, int countNum, int nums) {
//对数据进行校验
if(first == null || startNo < 1|| startNo > nums) {
System.out.println("参数输入有误,请重新输入~~");
return;
}
Child helper = first;
while(true) {
if(helper.next == first) {
break;
}
helper = helper.next;
}
for(int j = 0; j <startNo - 1; j++) {
first = first.next;
helper = helper.next;
}
while(true) {
if(helper == first) {
break;
}
for(int j = 0; j < countNum - 1; j++) {
first = first.next;
helper = helper.next;
}
System.out.printf("小孩%d出圈\n", first.no);
first = first.next;
helper.next = first;
}
System.out.printf("最后留在圈中的小孩的编号为%d\n", first.no);
}
}
//定义孩子结点
class Child{
public int no;
public Child next;
public Child(int no) {
this.no = no;
}
}