思路分析
1.首先需要建立起一个给定大小的环形链表,具体代码如下
public void add(int n) {
if (n < 1) {
System.out.println("增加个数不正确");
}
Boy cutBoy = null;
for (int i = 1; i <= n; i++) {
Boy boy = new Boy(i);
if (i == 1) {
first = boy;
boy.setNext(first);
cutBoy = first;
} else {
cutBoy.setNext(boy);
boy.setNext(first);
cutBoy = boy;
}
}
}
2.建立好环形链表后可以写一个方法去显示建立好的环形链表
public void show() {
if (first == null) {
System.out.println("链表为空");
return;
}
Boy cut = first;
while (true) {
System.out.println(cut);
cut = cut.getNext();
if (cut == first) {
break;
}
}
}
3.写一个出圈的方法,具体思路随代码注释写
/**
* @param startNo 从第几个小孩开始数
* @param countNum 隔几个数一次
* @param nums 圈内有多少个小孩
*/
public void countBoy(int startNo, int countNum, int nums) {
if (first == null || startNo < 0 || startNo > nums) {
System.out.println("数据有误");
}
//创建一个指针帮助节点出圈 单链表中上删除一定要指向节点的前一个
Boy temp = first;
while (true) {
if (temp.getNext() == first) {
break;
}
temp = temp.getNext();
}
//经过这样temp指针就指向环形链表的头指针的前一个
//开始位置StartNo则要把first与temp移动一下
for (int i=0;i<startNo-1;i++){
first=first.getNext();
temp=temp.getNext();
}
//开始移动出圈 循环操作 直到圈中只有一个节点
while (true){
if (temp==first){
//指向同一个节点时候,说明圈中只有一个节点
break;
}
for (int i=0;i<countNum-1;i++){
first=first.getNext();
temp=temp.getNext();
}
//这时候first小孩出圈
System.out.println("小孩 :"+first.getNo()+"出圈");
//循环链表跟新
first=first.getNext();
temp.setNext(first);
}
System.out.println("最后留在圈中的小孩"+first.getNo());
}
}
4.写个主方法进行验证
/**
* @author taoqianlilang
*/
public class YueSeFu {
public static void main(String[] args) {
CircleSingleLinkedList list = new CircleSingleLinkedList();
list.add(25);
list.countBoy(1,2,25);
}
5.代码实现全部代码
/**
* @Author: taoqianlilang
* @Description:
* @Date: Created in 10:19 2020/4/6
* @Modified By:
*/
class Boy {
private int no;
private Boy next;
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
Boy(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
@Override
public String toString() {
return "Boy{" +
"no=" + no +
'}';
}
}
class CircleSingleLinkedList {
//头节点不要动
/**
* 头节点
*/
private Boy first = null;
public void add(int n) {
if (n < 1) {
System.out.println("增加个数不正确");
}
Boy cutBoy = null;
for (int i = 1; i <= n; i++) {
Boy boy = new Boy(i);
if (i == 1) {
first = boy;
boy.setNext(first);
cutBoy = first;
} else {
cutBoy.setNext(boy);
boy.setNext(first);
cutBoy = boy;
}
}
}
public void show() {
if (first == null) {
System.out.println("链表为空");
return;
}
Boy cut = first;
while (true) {
System.out.println(cut);
cut = cut.getNext();
if (cut == first) {
break;
}
}
}
/**
* @param startNo 从第几个小孩开始数
* @param countNum 隔几个数一次
* @param nums 圈内有多少个小孩
*/
public void countBoy(int startNo, int countNum, int nums) {
if (first == null || startNo < 0 || startNo > nums) {
System.out.println("数据有误");
}
//创建一个指针帮助节点出圈 单链表中上删除一定要指向节点的前一个
Boy temp = first;
while (true) {
if (temp.getNext() == first) {
break;
}
temp = temp.getNext();
}
//经过这样temp指针就指向环形链表的头指针的前一个
//开始位置StartNo则要把first与temp移动一下
for (int i=0;i<startNo-1;i++){
first=first.getNext();
temp=temp.getNext();
}
//开始移动出圈 循环操作 直到圈中只有一个节点
while (true){
if (temp==first){
//指向同一个节点时候,说明圈中只有一个节点
break;
}
for (int i=0;i<countNum-1;i++){
first=first.getNext();
temp=temp.getNext();
}
//这时候first小孩出圈
System.out.println("小孩 :"+first.getNo()+"出圈");
//循环链表跟新
first=first.getNext();
temp.setNext(first);
}
System.out.println("最后留在圈中的小孩"+first.getNo());
}
}
/**
* @author taoqianlilang
*/
public class YueSeFu {
public static void main(String[] args) {
CircleSingleLinkedList list = new CircleSingleLinkedList();
list.add(25);
list.countBoy(1,2,25);
}
}