约瑟夫问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列,剩下一个人。
public class Juseph
{
public static void main(String[] args)
{
SysLink syslink = new SysLink();
syslink.setNodeLen(10);
syslink.createLink();
syslink.setBeginNo(5);
syslink.setM(5);
syslink.showLink();
syslink.start();
}
}
//环形链表类
class SysLink
{
//节点数
private int nodeLen=0;
//从第几个节点开始数数
private int beginNo;
//数几下
private int m;
//第一个节点
Node firstNode = null;
//设置游标
Node temp = null;
//设置节点数
public void setNodeLen(int len)
{
this.nodeLen = len;
}
//设置数几下
public void setM(int m)
{
this.m = m ;
}
//设置从第几个节点开始数
public void setBeginNo(int n)
{
this.beginNo = n ;
}
//创建环形链表
public void createLink()
{
//循环创建每个节点
for(int i = 1;i <= nodeLen;i++)
{
//当创建第一个节点时或者只有一个节点
if(i==1)
{
Node node=new Node(i);
//将firstNode节点指向新创建的第一个节点
this.firstNode = node;
//将temp节点指向新生成的节点
this.temp = node;
//将生成的节点指向头节点
node.next = firstNode;
}else
{
//当不是最后一个节点时
if (i!=nodeLen)
{
//新生成节点
Node node = new Node(i);
//将temp的下一个节点指向新生成的节点
this.temp.next = node;
//并将temp节点下移
this.temp = node;
}
//最后一个节点
else
{
Node node = new Node(i);
temp.next = node ;
temp = node ;
//将新生成节点指向第一个节点,形成环
node.next = firstNode;
}
}
}
}
//开始
public void start()
{
//找到开始数的节点
//从第一个节点开始
Node temp=this.firstNode;
for (int i = 1; i < beginNo; i++)
{
temp = temp.next ;
}
while(nodeLen!=1)
{
//数几下
for (int j = 0; j < m-1; j++)
{
temp = temp.next;
}
//找到temp前一个节点
Node temp2 = temp ;
while (temp2.next!=temp)
{
temp2= temp2.next;
}
//将temp除去
temp2.next = temp.next;
System.out.println("出圈的人是:"+temp.no);
temp = temp.next ;
this.nodeLen--;
}
System.out.println("最后剩下的是:"+temp.no);
}
//打印链表
public void showLink()
{
Node temp = this.firstNode;
//当只有一个节点时
if (temp.next.no == 1)
{
System.out.println(temp.no);
}else{
while (temp.next!=firstNode)
{
System.out.println(temp.no);
temp = temp.next;
}
}
System.out.println(temp.no);
}
}
//节点类
class Node
{
//节点的编号
int no;
//创建节点类型
Node next=null;
//构造函数
public Node(int no)
{
this.no=no;
}
}