参考博客:图解Java数据结构之环形链表
/**
* @author
* @create 2021-04-18 14:05
*/
public class CircleLinkedList {
//first指针
Boy first = null;
public void add(int num){
//数据校验
if (num < 0){
return;
}
//辅助指针,指向当前Boy
Boy curBoy = null;
//循环创建节点
for (int i = 0; i < num; i++) {
Boy boy = new Boy(i);
//第一个节点
if (i == 0){
first = boy;
first.next = first;
curBoy = first;
}else {
//其他节点
curBoy.next = boy;
boy.next = first;
curBoy = boy;//向后移动辅助指针
}
}
}
//遍历环形链表
public void show(){
if (first == null){
return;
}
Boy curBoy = first;
while (true){
System.out.println("节点" + curBoy.no);
if (curBoy.next == first){
//如果下一个节点为first,则遍历结束
break;
}
curBoy = curBoy.next;//向后移动
}
}
/**
*
* @param startNo 从几开始数
* @param countNum 数几下
* @param nums 有多少人
*/
public void countBoy(int startNo, int countNum, int nums){
if (first == null || startNo < 0 || startNo > nums){
return;
}
//辅助指针指向最后一个节点
Boy helper = first;
while (helper.next != first) {
helper = helper.next;
}
//将first和helper都向后移动startNo次。也就是从哪个数开始数
for (int i = 0; i < startNo; i++) {
first = first.next;
helper = helper.next;
}
//开始循环,当helper和first指向同一个节点时说明当前链表只剩下一个节点
while (helper != first) {
//将first和helper都向后移动countNum-1次
for (int i = 0; i < countNum - 1; i++) {
first = first.next;
helper = helper.next;
}
//此时first指向的节点就是要出圈的节点
System.out.println("节点" + first.no + "出圈");
//出圈
first = first.next;
helper.next = first;
}
System.out.println("最后剩下的节点为" + first.no);
}
public static void main(String[] args) {
CircleLinkedList circle = new CircleLinkedList();
circle.add(5);
circle.show();
circle.countBoy(0,3,5);//[0,1,2,3,4]
}
}
//创建Boy节点,包含no和next两个属性
class Boy{
int no;
Boy next;
public Boy(int no){
this.no = no;
}
}