约瑟夫环问题

Josephu问题为:设编号为1,2,...n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

    提示:用一个不带头结点的循环链表来处理Josephu问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点的人从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。


public class demo9 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Cyclelink cyclelink = new Cyclelink();
		cyclelink.setLen(5);
		cyclelink.initCyclelink();
		cyclelink.show();
		cyclelink.setK(2);//从第几个人开始数
		cyclelink.setM(2);//数几下
		cyclelink.play();
	}

}
 class Child{
	 int no;
	 Child nextchild = null;
	 public Child(int no){
		 this.no= no;
	 }
 }
 
 class Cyclelink{
	 Child firstchild = null;
	 Child temp =null;
	 int len = 0;
	 int m = 0;
	 int k = 0;
	 
	 public void setLen(int len){
		 this.len = len;
	 }
	 
	 public void setM(int m){
		 this.m = m;
	 }
	 
	 public void setK(int k){
		 this.k = k;
	 }
	 
	 public void play(){
		 //1找到第几个人开始
		 Child temp = this.firstchild;
		 for(int i=1;i<m;i++){
			 temp = temp.nextchild;
		 }
		 while(this.len!=1){
			//2.数k下
			 for(int i=1;i<k;i++){
				 temp = temp.nextchild;
			 }
			 //找到要出圈的前一个小孩
			 Child temp2 = temp;
			 while(temp2.nextchild != temp){
				 temp2 = temp2.nextchild;
			 }
			//3.将数到k的小孩,退出圈
			 temp2.nextchild = temp.nextchild;
			//让temp指向下一个数数的小孩
			temp=temp.nextchild;
			this.len--;
		 }
		 System.out.println();
		 System.out.println("最后出圈的小孩:"+temp.no);
	 }
	 
	 public void initCyclelink(){
		 for(int i=1;i<=len;i++){
			 if(i==1){
				 Child child = new Child(i);
				 firstchild = child;
				 temp = child;
			 }else{
				 if(i == len){
					 Child child = new Child(i);
					 temp.nextchild = child;
					 temp = child;
					 temp.nextchild = firstchild;
				 }else{
					 Child child = new Child(i);
					 temp.nextchild = child;
					 temp = child;
				 }
				 
			 }
		 }
	 }
	 
	 public void show(){
		 //定义个跑龙套
		 Child temp = firstchild;
		 do{
			 System.out.print(temp.no+" ");
			 temp = temp.nextchild;
		 }while(temp != this.firstchild);
	 }
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值