约瑟夫环问题(Josephus problem)

约瑟夫环问题:

约瑟夫问题,是一个计算机科学数学中的问题,在计算机编程算法中,类似问题又称为约瑟夫环,又称“丢手绢问题”。

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3。

这里我们换成孩子出环形队列的问题,杀人有点血腥.....

用Java链表实现

1.创建一个孩子的节点类:

class BoyNode{
	private int number;
	private BoyNode next;
	public BoyNode(int no) {
		this.number=no;
	}
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	public BoyNode getNext() {
		return next;
	}
	public void setNext(BoyNode next) {
		this.next = next;
	}
}

 这里的变量都是private私有型变量,所以使用set和get方法来调用和获取。

2.通过添加节点的方法来创建一个环形列表

public void addBoy(int num) {
		if(num<2) {
			System.out.println("num数字不符合要求");
			return;
		}
		//使用循环创建环形链表
		//创建一个辅助节点
		BoyNode curboy=null;//默认辅助节点为空
		for(int i=1;i<=num;i++) {
			BoyNode boy = new BoyNode(i);
			if(i==1) {
				first=boy; 
				first.setNext(first);
				curboy=first;
			}
			curboy.setNext(boy);
			boy.setNext(first);
			curboy=boy;
		}
	}
	

 3.遍历环形列表,检查是否有误

public void showList() {
		if(first==null) {
			System.out.println("当前循环链表为空");
			return;
		}
		BoyNode curboy=first;
		while(true) {
			System.out.printf("小孩的编号分别为%d\n",curboy.getNumber());
			if(curboy.getNext()==first) {
				break;
			}
			curboy=curboy.getNext();//curboy辅助变量向后移动。
		}
	}
	

4.约瑟夫环问题出列表

/**
	 * @param startnum  开始报数的位置
	 * @param count    数count个出环形链表
	 * @param num      总高有多少人
	 */
	public void countBoy(int startnum,int count,int num) {
		//先对数据进行校验
		if(first==null||startnum<1||startnum>num) {
			System.out.println("输入的数据不符合约定,请重新输入");
			return;
		}
		//创建辅助节点指向需要出链表的节点的前一个节点
		BoyNode helper=first;
		while(helper.getNext()!=first) {
			helper=helper.getNext();
		}
		
		//需要从哪一个孩子开始报数  就移动startnum-1次
		//此时first指向需要开始报数的孩子。
		for(int j=0;j<startnum-1;j++) {
			first=first.getNext();
			helper=helper.getNext();
		}
		while(helper!=first) {
			for(int j=1;j<count;j++) {
				first=first.getNext();
				helper=helper.getNext();
			}
			System.out.printf("%d号小孩出链表\n",first.getNumber());
			first=first.getNext();
			helper.setNext(first);
		}
		System.out.printf("最后一位孩子为%d号\n", first.getNumber());
		
	}
}

5.最后代码预览:

package Josephu;

public class Josephu {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		//测试代码
		CircleSingleLinkList list1=new CircleSingleLinkList();
		list1.addBoy(5);
		list1.showList();
		list1.countBoy(1, 2, 5);
	}

}
class CircleSingleLinkList{
	private BoyNode first = new BoyNode(-1);
	//添加孩子节点(其他节点)
	public void addBoy(int num) {
		if(num<2) {
			System.out.println("num数字不符合要求");
			return;
		}
		//使用循环创建环形链表
		//创建一个辅助节点
		BoyNode curboy=null;//默认辅助节点为空
		for(int i=1;i<=num;i++) {
			BoyNode boy = new BoyNode(i);
			if(i==1) {
				first=boy; 
				first.setNext(first);
				curboy=first;
			}
			curboy.setNext(boy);
			boy.setNext(first);
			curboy=boy;
		}
	}
	
	//遍历循环链表
	public void showList() {
		if(first==null) {
			System.out.println("当前循环链表为空");
			return;
		}
		BoyNode curboy=first;
		while(true) {
			System.out.printf("小孩的编号分别为%d\n",curboy.getNumber());
			if(curboy.getNext()==first) {
				break;
			}
			curboy=curboy.getNext();//curboy辅助变量向后移动。
		}
	}
	
	//按规则依次推出循环链表的顺序
	
	/**
	 * @param startnum  开始报数的位置
	 * @param count    数count个出环形链表
	 * @param num      总高有多少人
	 */
	public void countBoy(int startnum,int count,int num) {
		//先对数据进行校验
		if(first==null||startnum<1||startnum>num) {
			System.out.println("输入的数据不符合约定,请重新输入");
			return;
		}
		//创建辅助节点指向需要出链表的节点的前一个节点
		BoyNode helper=first;
		while(helper.getNext()!=first) {
			helper=helper.getNext();
		}
		
		//需要从哪一个孩子开始报数  就移动startnum-1次
		//此时first指向需要开始报数的孩子。
		for(int j=0;j<startnum-1;j++) {
			first=first.getNext();
			helper=helper.getNext();
		}
		while(helper!=first) {
			for(int j=1;j<count;j++) {
				first=first.getNext();
				helper=helper.getNext();
			}
			System.out.printf("%d号小孩出链表\n",first.getNumber());
			first=first.getNext();
			helper.setNext(first);
		}
		System.out.printf("最后一位孩子为%d号\n", first.getNumber());
		
	}
}

//创建一个节点类
class BoyNode{
	private int number;
	private BoyNode next;
	public BoyNode(int no) {
		this.number=no;
	}
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	public BoyNode getNext() {
		return next;
	}
	public void setNext(BoyNode next) {
		this.next = next;
	}
}

 写在最后:小兰学编程(一个学编程的一年级新生)

更多内容请关注微信公众号:小兰小栈

欢迎各位大神指点一二!!!


版权声明:本文为weixin_51232559原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。