数据结构之单向环形链表解决约瑟夫问题

一.单向环形链表构建图:

1.第一张:

 2.第二张

3.第三张

至此便成功插入一个节点到一个单向环形链表中

二.使用单向环形链表解决约瑟夫问题

        约瑟夫问题:设编号为1,2,3...,n的n个人围成一圈,约定编号为k(1<=k<=n)的人
从1开始报数,数到m的那个人出列,它的下一位从1数到m然后出列,
以此类推直到全部人出列为止,产生一个出队的编号序列

1.创建一个BoyNode类

public class BoyNode {
    /**
     * 编号
     */
    public int id;

    /**
     * 姓名
     */
    public String name;

    /**
     * 下一个节点
     */
    public BoyNode nextNode;

    public BoyNode(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "BoyNode{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

 2.创建一个BoyRingLinked类

public class BoyRingLinked {
    /**
     * 第一个节点
     */
    public BoyNode first;

    /**
     * 添加nodeSize个节点到环形链表中
     */
    public void addNode(int nodeSize){
        BoyNode temp = null;
        BoyNode current = null;
        for (int i=1;i<=nodeSize;i++){
            if (first == null){
                first = new BoyNode(i,""+i);
                first.nextNode = first;
                temp = first;
                continue;
            }
            if (temp.nextNode != null){
                current = new BoyNode(i,""+i);
                temp.nextNode = current;
                current.nextNode = first;
                temp = current;
            }
        }
    }

    /**
     * 查询环形链表中的节点
     */
    public void queryAllNode(){
        BoyNode current = first;
        if (current == null){
            System.out.println("空环形链表");
            return;
        } else {
            System.out.println(current);
        }
        while (true){
            if (current.nextNode == first){
                return;
            }{
                System.out.println(current.nextNode);
            }
            current = current.nextNode;
        }
    }

    /**
     * 调用此方法解决约瑟夫问题
     */
    public void ringLinkedOut(int start,int step,int nodeSize){
        addNode(nodeSize);
        BoyNode temp = queryBoyEndNode();
        for (int i=1;i<start;i++){
            temp = temp.nextNode;
        }
        for (;;){
            if (temp.nextNode == temp){
                System.out.println(temp);
                break;
            }
            for (int i=1;i<=step;i++){
                if (i == step){
                    System.out.println(temp.nextNode);
                    temp.nextNode = temp.nextNode.nextNode;
                    break;
                }
                temp = temp.nextNode;
            }
        }
    }

    /**
     * 查询双向链表的尾节点
     */
    public BoyNode queryBoyEndNode(){
        BoyNode current = first;
        while (true){
            if (current.nextNode == first){
                return current;
            }
            current = current.nextNode;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

持爱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值