约瑟夫问题:
class Josephu
{
public static void main(String[] args)
{
//测试
System.out.println("测试");
CircleSingleLinkedList circle = new CircleSingleLinkedList();
circle.addBoy(5);
circle.showBoy();
circle.countBoy(1,2,5); //2-4-1-5-3
}
}
//创建环形单向链表
class CircleSingleLinkedList
{
//创建一个first节点,没有编号
private Boy first = null;
//添加一个小孩节点,构建成环形链表
public void addBoy(int nums){ //nums为节点个数
//nums做一个数据校验
if (nums < 1)
{
System.out.println("nums的值不正确");
return;
}
Boy curBoy = null; //辅助指针,帮助构建环形链表
//使用for创建环形链表
for (int i = 1;i <= nums ;i++ )
{
//根据编号创建小孩节点
Boy boy = new Boy(i);
//如果是第一个小孩
if (i == 1)
{
first = boy; //first指向第一个节点
first.setNext(first); //构成环
curBoy = first; //让curBoy指向第一个节点
}else
curBoy.setNext(boy); //让当前节点连接新节点
boy.setNext(first); //让新节点连接头节点构成环
curBoy = boy; //将curBoy右移到新节点
}
}
//遍历当前环形链表
public void showBoy() {
//判断链表是否为空
if (first == null)
{
System.out.println("链表为空");
return;
}
//因为first不能动,使用辅助指针curBoy
Boy curBoy = first; //先指向first
while (true)
{
System.out.printf("小孩的编号为%d\n",curBoy.getNo());
if (curBoy.getNext() == first)
{
break;
}
curBoy = curBoy.getNext();
}
}
//根据用户的输入,计算小孩出圈的顺序
//startNo表示从第几个小孩开始数
//countNum表示数几下
//nums表示最初有几个小孩在圈中
public void countBoy(int startNo,int countNum,int nums) {
//先对数据进行校验
if (startNo < 1 || first == null || startNo > nums)
{
System.out.println("参数输入有误");
return;
}
//创建辅助指针,帮助完成小孩出圈
Boy helper =first;
//helper指向环形链表的最后这个节点
while (true)
{
if (helper.getNext() == first)
{
break;
}
helper = helper.getNext() ;
}
//先让first和helper移动startNo-1次,移动到开始的那个小孩
for (int i = 0;i < startNo - 1 ;i++ )
{
helper = helper.getNext();
first = first.getNext();
}
//出圈,让first和helper同时移动countNum-1次,直到圈中只有一个节点
while (true)
{
if (helper == first) //圈中只有一个节点
{
break;
}
//让first和helper同时移动countNum-1次
for (int i = 0;i< countNum -1 ;i++ )
{
helper = helper.getNext();
first = first.getNext();
}
//这时first指向的节点就是出圈的小孩的节点
System.out.println("小孩出圈" + first.getNo());
//出圈
first = first.getNext();
helper.setNext(first); //setNext()就是指自己的next指向括号里面,getNext()就是指下一个节点
}
System.out.printf("最后留下的小孩是%d",first.getNo());
}
}
class Boy
{
private int no; //编号
private Boy next; //指向下一个节点
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;
}
}