约瑟夫环介绍
添加节点思路分析
移出链表思路
1.创建一个helper指针 指向最后一个节点
2.在报数之前让 让helper和first 移动 start-1次 从第几个节点 开始
3.让helper 和first指针 向后移动 countNum-1次
4.出圈 让 first=first.next; helper.next=first;
结合代码查看
代码实现
package 链表;
/**
* @author 一介草莽子
* version 1.0
*/
@SuppressWarnings({
"all"})
public class josepfu {
public static void main(String[] args) {
JosePfuLinkedList josePfuLinkedList = new JosePfuLinkedList();
josePfuLinkedList.add(125);
josePfuLinkedList.Print();
josePfuLinkedList.RemoveBoy(2,4,125);
}
}
class JosePfuLinkedList {
private Boy first;//创建一个头结点first 即是头结点有是第一个小孩
/**
* @param startNum 从那个小孩开始
* @param countNum 循环几次踢出一个去
* @param nums 最初小孩的个数
* 1.创建一个helper指针 指向最后一个节点
* 2.在报数之前让 让helper和first 移动 start-1次 从第几个节点开始
* 3.让helper 和first指针 向后移动 countNum-1次
* 4.出圈 让 first=first.next; helper.next=first;
*/
public void RemoveBoy(int startNum, int countNum, int nums) {
//判断合法性
if(startNum<0||countNum<1||first==null||nums<1){
throw new RuntimeException("数据不合法");
}
//1.创建一个helper指针 指向最后一个节点
Boy helper=first;
while (helper.getNext()!=first){
helper=helper.getNext();
}
//2.在报数之前让 让helper和first 移动 start-1次 从第几个节点开始
for (int i = 0; i < startNum-1; i++) {
helper=helper.getNext();
first=first.getNext();
}
while (true) {
if(first==helper){
break;//两个指针指向同一个就退出
}
//3.让helper 和first指针 向后移动 countNum-1次【也就是喊号了】
for (int i = 0; i < countNum - 1; i++) {
helper = helper.getNext();
first = first.getNext();
}
System.out.printf("出圈的小孩是%d\n",first.getNo());
//4.出圈 让 first=first.next; helper.next=first;
first=first.getNext();
helper.setNext(first);
}
System.out.println("最后小孩是 ="+first.getNo());
}
//形成约瑟夫环 nums是该环有几个节点
public void add(int nums) {
if (nums < 1) {
throw new RuntimeException("nums不能小于1");
}
Boy curBoy = null;
for (int i = 1; i <= nums; i++) {
Boy boy = new Boy(i);
if (i == 1) {
first = boy;
first.setNext(boy);//第一个自己指向自己
curBoy = first;
} else {
curBoy.setNext(boy);
boy.setNext(first);//新的节点在指向下一个
curBoy = boy;
}
}
}
//打印环
public void Print() {
if (first == null) {
throw new RuntimeException("空链表");
}
Boy temp = first;
while (true) {
System.out.printf("[%d] ", temp.getNo());
if (temp.getNext() == first) {
break;//指向了第相同的就退出
}
temp = temp.getNext();
}
System.out.println();
}
}
//小孩类
class Boy {
private int no;
private Boy next;
public Boy(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public Boy getNext() {
return next;
}
public void setNo(int no) {
this.no = no;
}
public void setNext(Boy next) {
this.next = next;
}
}