约瑟夫环问题
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知 n 个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。. 从编号为 k 的人开始报数,数到 m 的那个人出圈;他的下一个人又从 1 开始报数,数到 m 的那个人又出圈;依此规律重复下去,直到剩余最后一个胜利者
环形单向链表解决
package data_structure.CircleList;
public class Circle1
{
public static void main(String[] args)
{
CircleList circleList = new CircleList();
circleList.add(8);
circleList.showBoy();
circleList.count(3,7,8);
}
}
class CircleList
{
//创建first节点,当前没有编号
private Boy first = null;
//添加节点
public void add(int nums)
{
if (nums < 1)
{
System.out.println("nums 值不正确");
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.println("编号 " + temp.getNo());
if (temp.getNext() == first)//遍历完毕
{
break;
}
temp = temp.getNext();
}
}
//根据用户输入,计算出出圈顺序
public void count(int statNo, int countNum, int nums)
{
if (first == null || statNo < 1 || statNo > nums)
{
System.out.println("输入数据有误");
return;
}
Boy temp = first;//辅助节点
//移动temp到first的后面
while (true)
{
if (temp.getNext() == first)
{
break;
}
temp = temp.getNext();
}
//报数前的移动
for (int i = 0; i < statNo - 1; i++)
{
first = first.getNext();
temp = temp.getNext();
}
//开始报数
while (true)
{
if (first == temp)
{
break;
}
for (int j = 0; j < countNum - 1; j++)
{
first = first.getNext();
temp = temp.getNext();
}
//这时first指向的节点就是要出圈的节点
System.out.println("编号"+first.getNo()+"出圈");
first = first.getNext();//first 前移
temp.setNext(first);//temp依然跟在first后面
}
System.out.println("最后的一个人编号:"+first.getNo());
}
}
//创建一个Boy类,表示一个节点
class Boy
{
private int no; //编号
private Boy next;//指向下一个节点,默认null
public Boy(int no)
{
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;
}
}