约瑟夫问题(Java环形列表实现)

2023-10-26

package linkedList;

public class Joseph {
	public static void main(String[] args) {
		CircleLinkList cir = new CircleLinkList();
		cir.addBoy(15);
		cir.getAllInfo();
		cir.countBoy(1, 2, 15);
	}
}

// 创建环形的单向链表
class CircleLinkList {
//	创建一个first检点
	private Boy first = null;

//	添加小孩
	public void addBoy(int nums) {
		if (nums < 1) {
			System.out.println("输入不符合规范");
			return;
		}
		Boy curBoy = null;
		for (int i = 1; i <= nums; i++) {
			Boy boy = new Boy(i);
//			if is the first boy?
			if (i == 1) {
				first = boy;
				first.setNext(first);// 成环
				curBoy = first;
			} else {
//				环状链表加入一个节点
				curBoy.setNext(boy);
				boy.setNext(first);
				curBoy = boy;
			}
		}
	}

	public void getAllInfo() {
		if (first.getNext() == null) {
			System.out.println("链表为空");
			return;
		}
		Boy curBoy = first;
		while (true) {
			System.out.printf("小孩编号 %d \n", curBoy.getNo());
			if (curBoy.getNext() == first) {
				break;
			}
//			curBoy = curBoy.getNext();
			curBoy = curBoy.getNext();
		}
	}

//	根据用户的输入,计算出小孩出圈的顺序
	/**
	 * 
	 * @param startno 表示从第几个小孩计数
	 * @param countno 表示数几下
	 * @param num     最初由多少个小孩在圈里面
	 */
	public void countBoy(int startno, int countno, int num) {
//		num表示最初有多少个小孩在圈里面
		if (first == null || startno > num || startno < 1) {
			System.out.println("输入参数不合理!");
			return;
		}
		Boy helper = first;
//		这里的死循环为了找到最后一个节点
		while (true) {
			if (helper.getNext() == first) {
//				找到了最后的节点
				break;
			}
			helper = helper.getNext();
		}
//		先移动到准备开始位置
//		因为其本身就需要报数,因此循环为1开始
		for (int j = 1; j < countno - 1; j++) {
			first = first.getNext();
			helper = helper.getNext();
		}
//然后计数开始移动
		while (true) {
			if (helper == first) {
//				这里是只剩了最后一个小孩
				break;
			}
//			开始移动
			for (int j = 0; j < countno - 1; j++) {
				first = first.getNext();
				helper = helper.getNext();
			}
			System.out.printf("小孩%d出圈 \n", first.getNo());
//			删除出圈小孩节点
			first = first.getNext();
			helper.setNext(first);
			
		}
		System.out.printf("小孩%d出圈 \n",helper.getNo());
	}

	class Boy {
		private int no;// 编号
		private Boy next;// 下一个节点

		public Boy(int no) {
			this.no = no;
		}

		public int getNo() {
			return no;
		}

		public void setNo(int no) {
			this.no = no;
		}

		public Boy getNext() {
			return next;
		}

		public void setNext(Boy next) {
			this.next = next;
		}
	}
}

里面有些需要考虑到的细节,循环次数与完成条件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

约瑟夫问题(Java环形列表实现) 的相关文章

随机推荐