1.约瑟夫问题
1.1 基本目的
使用循环单链表实现有密码的约瑟夫问题,即每次出局的人会更改计数上限,每个人身上都会附带一个密码。输入每个人的信息,输出出局的顺序。
1.2 核心代码
1.2.1 实现方法
public void test(int pass,Node node){
if(length==0)
return;
for(int i=1;i<pass;i++)
{
node=node.next;
}
System.out.println(node.name+" "+node.number+" ");
Node tem=node;
delete(node.number);
test(tem.password,tem.next); //继续调用test方法,模拟继续游戏
}
传进来的pass即为计数数量,node为开始计数的第一个人,通过循环找到再次满足规则的人,将其输出出来,并调用链表的delete方法将其删除(length作为游戏的人数会一直被减少),并再次调用test方法,直到length为0,停止调用。
1.2.2 delete方法
public void delete(int number){
if(length==0)
return;
if(length==1)// 当长度为1时将head和last置空
{
head=null;
last=null;
length--;
return;
}
Node tem=head;
while(tem.next.number!=number){
tem=tem.next;
}
if(tem.next.number==head.number)//更新head和last
head=tem.next.next;
if(tem.next.number==last.number)
last=tem;
tem.next=tem.next.next; //执行删除操作
length--;
}
当长度为1的时候,使用寻找前一个结点进行删除的方法不再适用,因为循环单链表下,会永远使得自己指向自己。而当删除头尾结点时候,将头尾结点对应更新,否则当面临游戏还没进行完,而有重新插入新人的情况,会出现错误。
1.3 输入输出
public static void main(String[] args) {
Circle ans=new Circle();
ans.add("jack",1,2);//其中字符串为姓名,第一个数字为序号,
//第二个数字为所带的密码
ans.add("Amy",2,3);
ans.add("daming",3,4);
ans.add("myx",4,5);
ans.show(); //显示目前参加的人名和顺序
System.out.println();
ans.test(3,ans.head);//设初始密码为3,将头节点传入进行游戏
}
下为对应输出:
———————————————————————————————
欢迎来我的博客看看