一:循环链表的思想
问题:
思想:如果是第一个结点,自己指向自己,如果结点数不止一个的话的话那么就需要一个辅助结点来判断此时结点到了哪里(类似于之前的temp标记),就是找到链表的在最后一个结点,还需要first始终标记第一个结点。
二:环形链表的搭建
first标记第一个节点,temp标记最后一个节点(3个必须结点)
public void addBoy(int num) {
if(num < 1) {
System.out.print("数据不正确");
return;
}
//创建第一个结点的标记
Boy first = new Boy(-1);
//创建最后一个结点的标记
Boy temp = null;
for(int i = 1; i <= num; i++) {
Boy boy = new Boy(i);
if(i == 1) {
first = boy;
first.setNext(first);
temp = first;
}else {
temp.setNext(boy);
boy.setNext(first);
temp = boy;
}
}
}
三:查看循环链表
和单向链表不同,没有空的头结点
//查看循环链表
public void showBoy() {
if(first == null) {
System.out.print("空链表");
return;
}
Boy boy = first;
while(true) {
System.out.printf("小孩子的编号%d\n" + boy.getNo());
if(boy.getNext() == first) {
break;
}
boy = boy.getNext();
}
}
四:约瑟夫环问题解决
约瑟夫环:寻找起始位置->寻找符合步数的结点->出链表(两个必须结点)
public void countBoy(int startno, int countnum, int num) {
if(first == null || startno < 1 || startno > num) {
System.out.print("有问题");
return;
}
Boy helper = first;
while(true) {
if(helper.getNext() == first) {
break;
}
helper = helper.getNext();
}
//寻找起始位置
for(int j = 0; j < startno - 1; j++) {
first = first.getNext();
helper = helper.getNext();
}
//找到出列的那个孩子
while(true) {
if(first == helper) {
break;
}
for(int j = 0; j < countnum - 1; j++) {
first = first.getNext();
helper = helper.getNext();
}
System.out.printf("小孩子%d出列\n",first.getNo());
first = first.getNext();
helper.setNext(first);
}
System.out.printf("最后一个孩子%d出列\n", first.getNo());
}
结果: