约瑟夫环的java实现

注释很详细,就不细讲了,上代码。

/**
 * 10、 有100个人围成一个圈,从1开始报数,
 * 报到14的这个人就要退出。然后其他人重新
 * 开始,从1报数,到14退出。问:最后剩下
 * 的是100人中的第几个人?
 */

public class Test10 {

	public static void main(String[] args) {
		Test10 test = new Test10();
		int lastP = test.getLastPerson(100, 14);
		System.out.println("\r\n最后还剩下第"+lastP+"个人。");
	}
	
	/*
	 * 解题思路,用二维数组模拟一个线性链表,数组第一位存储当前位置,第二位存储该位置的下一位置,
	 * 当到达(报数-1)位置时,则下一位置为要被删除。则将下一位置数组的第二位存储的值赋给当前(报数-1)位置。
	 * 模拟报数位置删除的过程。依次,直到数组还剩余一个元素。
	*/
	public int getLastPerson(int totalPerson,int outNum){
		//根据传入参数,构建一个二维数组
		int [][] person = new int[totalPerson][2];
		//模拟链表,数组第一位存自己位置,第二位存与之相邻的下一位置
		for(int i=0;i<totalPerson;i++){
			person[i][0]=i;
			person[i][1]=i+1;
		}	
		//将数组最后一位指向数组第一位,模拟一个环形链表
		person[totalPerson-1][1]=0;
		int index=0;//记录每次删除位置的前一位置
		System.out.println("出局顺序为:");
		//当模拟链表中只剩一个元素,即自己指向自己时,程序退出。		
		while(index != person[index][1] ){
			//模拟一次报数
			for(int i=1;i<=outNum;i++){			
				if(i == (outNum-1)){
					//输出出局元素
					System.out.print(person[index][1]+1+"  ");
					/*
					 * 到达要删除位置的前一位置(因为如果直接到达删除位置,就要将当前位置的前一位置
					 * 指向当前位置的后一位置,模拟删除,但是由于是单向链表,前位置取不到,所以到达
					 * 要删除位置的前一位置比较好处理。)
					 * */				
					person[index][1] = person[person[index][1]][1];					
					//记录当前位置
					index =person[index][1];		
					//已删除,则此次报数完成,退出循环
					break;
				}
				else{
					//没到达指定位置,则按步数往后走
					index=person[index][1];
				}				
			}	
		}
		//返回下标+1,即第几个人
        return index+1;  
		
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值