环形单链表之约瑟夫问题

创建环形链表 

小孩出圈

 Josephu问题的代码实现

package citclelinklist;

public class Josepfu {
    public static void main(String[] args) {
        circleLinkList circleLinkList = new circleLinkList();
        circleLinkList.addBoy(5);//加入5个小孩节点
        circleLinkList.showBoy();
        circleLinkList.countBoy(1,2,5);
    }

    }
    class circleLinkList {
        //创建一个first节点
        Boy first = new Boy(-1);

        public void addBoy(int nums) {
            if (nums < 1) {
                System.out.println("nums的值不正确");
                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 = 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.printf("小孩的编号为%d\n", curBoy.getNo());
                if (curBoy.getNext() == first) {//说明遍历完成
                    break;
                }
                curBoy = curBoy.getNext();//    curBoy后移
            }
        }

        /**
         *
         * @param starNum  表示从第几个小孩开始数数
         * @param countNum  表示数几下
         * @param nums  表示小孩的个数
         */
        public  void countBoy(int starNum,int countNum,int nums){
                if(first == null||starNum < 1||starNum>nums){
                    System.out.println("参数输入有误,请重新输入");
                }
                //创建辅助指针
                Boy helper = first;
                while(true){
                    if(helper.getNext() == first){
                        //helper指向了最后的节点
                        break;
                    }
                    helper = helper.getNext();
                }
                //小孩报数前先让helper和first移动k-1次
            for (int i = 0; i < starNum - 1; i++) {
                first = first.getNext();
                helper = helper.getNext();
            }
            //当小孩报数时让first和helper移动m-1次,然后出圈
            //直到圈中只有一个人
           while (true){
               if(helper == first){//圈中只有一个人了
                   break;
               }
               for (int j = 0; j < countNum - 1; j++) {
                   first = first.getNext();
                   helper = helper.getNext();
               }
               //这是first所指向的节点,就是要出圈的节点
               System.out.printf("出圈小孩的编号为%d\n",first.getNo());
               first = first.getNext();
               helper.setNext(first);

           }
            System.out.printf("最后留在圈中的小孩编号是%d\n",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;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值