package CircleLinkedList;
/**
* 根据用户的输入
*/
public class Joseph {
public static void main(String[] args) {
CircleBoy circleBoy = new CircleBoy();
circleBoy.addBoy(5);
circleBoy.showBoy();
System.out.println("--------------");
circleBoy.outCircle(1,2,5);//2 4 1 5 --> 3
}
}
// 创建一个环形的单向链表
class CircleBoy{
// 创建一个first节点,当前没有编号
private Boy first = null;
// 添加小孩节点,构建成一个环形的链表
public void addBoy(int nums){
//nums表示小孩的个数
if(nums < 1){
System.out.println("数值不正确,重新输入");
return;
}
Boy curBoy = null;
for(int i = 1; i <= nums; i++){
Boy boy = new Boy(i);
if(i == 1){
first = boy;
first.setNext(first);
curBoy = boy;
}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.printf("%d ",curBoy.getNo());
if (curBoy.getNext() == first){
break;
}
curBoy = curBoy.getNext();
}
}
//小孩出圈,从第k个开始报数,1报到m, 初始共有n 个人
public void outCircle(int k, int m, int n){
if(first == null || k < 1 || m > n){
System.out.println("数据不合理");
return;
}
Boy helper = first;//指向first的后一个
while (helper.getNext() != first){
helper = helper.getNext();
}
//从第k个开始报数,先让first,helper往前走 k - 1 步
for(int i = 0; i < k - 1; i++){
first = first.getNext();
helper = helper.getNext();
}
//从第k个开始数,即first、helper往前走 m - 1 步,然后first 出圈-->first = first.next,helper.next = first
while (true){
if(helper == first){
break;//只剩下最后一个男孩在圈中
}
for(int i = 0; i < m - 1; i++){
first = first.getNext();
helper = helper.getNext();
}
//出圈
System.out.printf("%d出圈\n",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 void setNo(int no){
this.no = no;
}
public int getNo(){
return no;
}
public void setNext(Boy next){
this.next = next;
}
public Boy getNext(){
return next;
}
}
环形单链表实现约瑟夫环问题
最新推荐文章于 2022-03-26 22:16:22 发布