//创建一个环形的单向链表
static class CircleSingleList
{
//创建一个first节点,当前没编号
private Boy first=new Boy(-1);
//添加小孩节点 构建成环境链表
public void addBoy(int nums)
{
//nums 判断
if(nums<1)
{System.out.println("nums错误");
return;}
Boy curBoy=null;//辅助指针 帮助构建环形链表
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;
}
// System.out.println(curBoy.getNo());
}
}
//遍历链表
public void showBoy()
{
if(first==null)return;
//因为first不能动 使用辅助指针完成遍历
Boy cur=first;
while (true)
{
System.out.println(cur.getNo());
if(cur.getNext()==first)
break;
cur=cur.getNext();
}
}
//根据用户的输入,计算出小孩出圈的顺序
/**
*
* @param startNo 从第几个小孩数
* @param countNum
* @param nums 有几个小孩在圈中
*/
public void countboy(int startNo,int countNum,int nums)
{
//对数据校验
if(first==null||startNo<1||startNo>nums)
{
System.out.println("参数输入有误");
return;
}
//创建一个辅助指针 帮助完成小孩出圈
Boy helper=first;
while (helper.getNext()!=first)
{
helper=helper.getNext();
}
//小孩报数前 先让first 和helper 移动startNo-1次
for(int j=0;j<startNo-1;j++)
{
first=first.getNext();
helper=helper.getNext();
}
//小孩报数前,first 和helper同时移动countNum-1次,然后出圈
while (helper!=first)//说明圈中只有一个人
{
for(int j=0;j<countNum-1;j++)
{
first=first.getNext();
helper=helper.getNext();
}
//这是first 指向的节点就是小孩要出圈的节点
System.out.printf("小孩%d出圈",first.getNo());
first=first.getNext();
helper.next=first;
}
System.out.printf("最后留在圈中的小孩%d编号",first.getNo());
}
}
//创建一个Boy类
static class Boy
{
private int no;
private Boy next;
public void setNo(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
public Boy(int no)
{
this.no=no;
}
}
约瑟夫环
最新推荐文章于 2024-08-11 21:58:53 发布