利用单向环形链表解决约瑟夫问题

利用单向环形链表解决约瑟夫问题

在这里插入图片描述

package List;

/**
 * 解决约瑟夫问题
 */
public class SingleCircleListDemo {
    public static void main(String[] args) {
        SingleCircleList list = new SingleCircleList();
        list.AddBoys(5);
        list.ShowList();
        System.out.println(list.GetLinkLength());
        list.CountBoy(1,2,5);
    }
}

class SingleCircleList{
    /**
     * 建立一个约瑟夫问题
     * 添加孩子
     * @param nums
     */
    Boy first = null;

    public void AddBoys(int nums){
        if (nums < 2){
            System.out.println("您输入的数据太少,至少输入两个!");
            return;
        }
        Boy cur = null;
        for (int i = 1; i <= nums; i++) {
            Boy boy = new Boy(i);
            if (i == 1){                  //添加第一个小孩,它的指针指向自己
                first = boy;
                first.setNext(boy);
                cur = first;
            }
            else {
                cur.setNext(boy);
                boy.setNext(first);
                cur = boy;
            }
        }
    }

    /**
     * 展示环形链表的值
     */
   public void ShowList(){
        if (first == null){
            System.out.println("没有孩子,没有值");
            return;

        }
        Boy cur = first;
        while (true){
            System.out.printf("孩子的编号为%d\n",cur.getNumber());
            if (cur.getNext() == first){
                break;
            }
            cur = cur.getNext();
        }
    }

    /**
     *
     * @param startNo  从第几名同学开始
     * @param countNum   间隔几人
     * @param nums     总共多少人
     */
    public void CountBoy(int startNo,int countNum,int nums){
      //对数据进行校验
        if (startNo < 1 || startNo > nums || nums < 0 || first == null){
            System.out.println("输入的参数不合格");
            return;
        }
        Boy helper = null;
        helper = first;
        while (helper.getNext() != first){
            helper = helper.getNext();
        }
        for (int i = 0; i < startNo - 1; i++) {
            first = first.getNext();
            helper = helper.getNext();
        }
        while (true){
            if (helper == first){
                break;
            }
            for (int i = 0; i < countNum - 1; i++) {
                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());

    }

    /**
     * 返回环形链表一轮的长度
     * @return
     */
    public int GetLinkLength(){
        Boy cur = null;
        cur = first;
        int number = 0;
        while (true){
            if (cur.getNext() == first){
                number++;
                break;
            }
            number++;
            cur = cur.getNext();
        }
        return number;
    }
}

class Boy{
    private int number;
    private Boy next;

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

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public Boy getNext() {
        return next;
    }

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

    @Override
    public String toString() {
        return "Boy{" +
                "number=" + number +
                '}';
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小猪~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值