java实现约瑟夫环形问题
间隔m个
开始为第n个人
思路:
1、初始helper指针进行移动,将该指针指向环形链表的最后一个
2、将first和helper指针 同时移动n-1次(使first指针为第一个出队的人)
3、将first指向的节点进行出队
first = first.getNext();
helper.setNext(first);
package com.it.likedList;
/**约瑟夫环形问题
* @author Snail-Bo
* @date 2020/4/1 16:09
*/
public class Josepfu {
public static void main(String[] args) {
JosepfuLinkedList list = new JosepfuLinkedList();
list.add(5);
list.showBoy();
System.out.println("出队的顺序为:");
list.getOut(2,3,5);
}
}
class JosepfuLinkedList{
//创建第一个节点
private Boy first = null;
public void add(int nums){
if(nums<1){
System.out.println("输入的num值不对");
return;
}
Boy temp=null; //创建辅助指针
for (int i = 1; i <=nums; 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.println("链表为空");
return;
}
Boy temp = first;
while (true){
System.out.printf("小孩编号为:%d\n",temp.getId());
if(temp.getNext()==first){ //当辅助节点的后一个节点为first节点时,则遍历完毕
break;
}
temp=temp.getNext();//后移
}
}
/**
*出队
* @param startId 初始的位置
* @param num 数num下就开始出队
* @param size 总人数
*/
public void getOut(int startId,int num,int size){
//开始位置<1,或者开始位置大于总人数
if(startId<1||startId>size||first==null){
System.out.println("参数输入有误");
return;
}
//创建辅助的节点
Boy helper =first;
//将helper节点遍历指向first节点的后一个节点
while (true){
if(helper.getNext()==first){
break;
}
helper=helper.getNext();
}
//将first和heleer 都移动到开始的位置 (从自己本身开始数,所有只需要移动startId-1次
for (int i = 0; i <startId-1 ; i++) {
first=first.getNext();
helper=helper.getNext();
}
//开始报数出圈
while (true){
//为最后一个数时,结束循环
if(first==helper){
break;
}
//将两个指针后移num-1次 ,使first 指针指向需要移出的节点上
for (int i = 0; i < num-1; i++) {
first=first.getNext();
helper=helper.getNext();
}
//进行出圈
System.out.printf("出圈的为%d\n",first.getId());
//将first指针后移 heper的后一个指向first的节点,完成出圈操作
first=first.getNext();
helper.setNext(first);
}
System.out.printf("最后的为%d\n",first.getId());
}
}
class Boy{
private int id;
private Boy next; //指向下一个节点
public Boy(int id){
this.id=id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
@Override
public String toString() {
return "Boy{" +
"id=" + id +
'}';
}
}