package com.sun.linkedlist;
public class 约瑟夫问题 {
public static void main(String[] args) {
//构建环形链表
CircleSingleLinkedList circleSingleLinkedList=new CircleSingleLinkedList();
circleSingleLinkedList.addBoy(5);
circleSingleLinkedList.showBoy();
//一圈有5个人,从第一个开始报数,每隔2个出去
circleSingleLinkedList.countBoy(1,2,5);
}
}
class CircleSingleLinkedList{
//创建第一个first节点,无编号
private Boy first=null;
//添加小孩节点,构建成一个环形链表
//构建一个单向环形链表思路:
/* 1. 先创建第一个节点,让first指向该节点,并形成环形
* 2.后面每创建一个新的节点,就把节点添加到已有的环形链表中
*
遍历链表
1.先让辅助变量curboy=first,即指向first节点
* 2.通过while循环遍历
*/
public void addBoy(int nums) {
if(nums<1){
System.out.println("nums值不正确");
return;
}
Boy curBoy=null;//辅助指针
//使用for创建环形链表
for (int i = 1; i <=nums; i++) {
Boy boy=new Boy(i);
if(i == 1){
first=boy;
first.setNext(first);//构成环状
curBoy=first; //用辅助变量指向第一个
}else{
curBoy.setNext(boy);
boy.setNext(first);
curBoy=boy;
}
}
}
public void showBoy() {
if(first == null){
System.out.println("没人!");
return;
}
Boy curBoy=first;//辅助指针
while(true){
System.out.println("小孩的编号:"+curBoy.getNo());
if(curBoy.getNext() == first){
break;
}
curBoy=curBoy.getNext();
}
}
public void countBoy(int startNo,int countNum,int nums) {
if(first ==null || startNo < 1 || startNo>nums){
System.out.println("参数错误");
return;
}
Boy helper=first;
//创建一个辅助变量helper,事先应该指向环形链表的最后这个节点
while(true){
if(helper.getNext() == first){
break;
}
helper=helper.getNext();
}
//小孩报数前,让first和helper指针同时移动k-1次
for(int j=0; j<startNo-1;j++){
first=first.getNext();
helper=helper.getNext();
}
//当小孩报数时,让first和helper指针同时移动m-1次countNum
while(true){
if(helper == first){
break;
}
for(int j=1; j<countNum;j++){
first=first.getNext();
helper=helper.getNext();
}
System.out.println("小孩:"+first.getNo()+"出圈");
first = first.getNext();
helper.setNext(first);
}
System.out.println("最后留在圈中的小孩编号:"+first.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;
}
}
10-10
1035