package com.wang;
public class Josepfu {
public static void main(String[] args) {
// TODO 自动生成的方法存根
CircleList circleList = new CircleList();
circleList.addBoy(5);
circleList.showBoy();
circleList.outBoy(1, 2, 5);
}
}
//创建一个单向环形链表
class CircleList{
//创建一个first节点当前没有编号
private Boy first=null;
//添加小孩节点形成环形链表
public void addBoy(int nums) {
if (nums < 1) {
return;
}
//辅助指针
Boy curBoy=null;
//使用for来创建环形链表
for (int i = 1; i <= nums; i++) {
//根据编号创建小孩节点
Boy boy = new Boy(i);
//如果是第一个节点
if (i==1) {
first =boy;
//构成环
first.setNext(first);
curBoy = first;
}else {
curBoy.setNext(boy);
boy.setNext(first);
curBoy=boy;
}
}
}
//遍历
public void showBoy() {
if (first==null) {
System.out.println("空");
return;
}
Boy curBoy=first;
while(true) {
System.out.println(curBoy.getNo());
if (curBoy.getNext() == first) {
break;
}
curBoy=curBoy.getNext();
}
}
/**
* 小孩出圈
* @param startNo表示从第几个小孩开始数数
* @param countNum表示数几下
* @param nums表示最初有多少小孩在圈中
*/
public void outBoy(int startNo,int countNum,int nums) {
if (first==null||startNo<1||startNo>nums) {
return;
}
Boy helper=first;
while(true) {
if (helper.getNext()==first) {
break;
}
helper=helper.getNext();
}
//小孩报数前,让first和helper移动k-1次,也就是移动到startNo的位置
for(int j = 0; j < startNo-1; j++) {
first=first.getNext();
helper = helper.getNext();
}
//当小孩报数时,让first和helper同时移动m-1次,然后出圈
while (true) {
if (helper==first) {
break;
}
//让first和helper同时移动countNum-1
for(int j=0;j<countNum-1;j++) {
first=first.getNext();
helper = helper.getNext();
}
//循环结束后first指向目标节点
System.out.println(first.getNo()+"出圈");
//将其出圈
first = first.getNext();
helper.setNext(first);
}
System.out.println("最后的节点"+first.getNo());
}
}
//创建Boy类代表一个节点
class Boy{
private int no;
private Boy next;
public Boy(int no) {
super();
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
}
单向循环链表-约瑟夫问题
最新推荐文章于 2024-08-18 21:47:10 发布