Java数据结构 学习约瑟夫问题的单链表解决 Joswphu

目录

// 节点类:制造小孩

//单链表的功能类

     * 添加n个小孩

     * 检查链表是否为空

     * 遍历链表

     * 实现约瑟夫环

//主函数


// 节点类:制造小孩

class Kid {

    // 封装,方便信息的录入和使用

    private int no;

    private Kid next;



    public Kid(int no) {

        this.no = no;

    }



    public int getNo() {

        return no;

    }



    public void setNo(int no) {

        this.no = no;

    }



    public Kid getNext() {

        return next;

    }



    public void setNext(Kid next) {

        this.next = next;

    }



}

//单链表的功能类

class Linked {

    private Kid head = null;

    /**

     * 添加n个小孩

     * @param no

     * 头结点:将第一个小孩作为头结点,并且放入数据

              让头结点指向自己

              辅助节点指向头。

     * 其余节点:将加入的节点放在链表的最后一个

                并让他指向头结点:形成环

                辅助节点指向该点。

     */

 

    public void addtoLinked(int n) {

        if (n <= 0) {

            System.out.println("N:Wrong");

            return ;

        }

        Kid node = head;//辅助节点

        /**

         * [0,n) ---->[1,n]

         */

        for (int i = 1; i <= n+1 ; i++) {

            /**

             * 创建小孩,同时给小孩加上编号i

             */

            Kid k = new Kid(i);

            if (i == 1) {

                /**

                 * 将第一个小孩作为头结点,并且放入数据

                 * 让头结点指向自己

                 * 辅助节点指向头。

                 */

                head = k;

                k = head;

                k.setNext(k);

                node = k;

            } else {

                /**

                 * 将加入的节点放在链表的最后一个

                 * 并让他指向头结点:形成环

                 * 辅助节点指向该点。

                 */

                node.setNext(k);

                k.setNext(head);

                node = k;

            }

        }

    }

    /**

     * 检查链表是否为空

     * @return 头结点是否指向空

     */

    public boolean isEmpty() {

        return head.getNext() == null;

    }

    /**

     * 遍历链表

     * 辅助节点从头结点开始遍历,当辅助节点重新指向头时,遍历结束

     */

    public void show() {

        if (isEmpty()) {

            System.out.println("Empty");

            return ;

        }

        Kid node = head;// 可移动的辅助节点

        while (true) {

            /**

             * 当辅助节点重新指向头时,遍历结束

             */

            if(node.getNext()==head){

                break;

            }

            //显示节点保存的编号值

            System.out.print(node.getNo()+" ");

            //辅助节点移动到下一个节结点

            node=node.getNext();

        }

        System.out.println("");

    }

    /**

     * 实现约瑟夫环

     * @param strat,从几开始

     * @param count,数几个数

     * @param n,最初的总数

     */   

public void JoswphuRolling(int strat,int count,int n){

        //即将出局的人

        Kid out=head;

        //辅助变量last需要成为链表的最后一个值

        Kid last=head;

        if(strat<0||n<0||count<0){

            System.out.println("数据出错");

            return;

        }

        while (true) {

            if(last.getNext()==head){

                break;

            }

            last=last.getNext();

        }

        //将out移到开始的位置,last跟随他

        for (int i = 0; i < strat-1; i++) {

            out=out.getNext();

            last=last.getNext();

        }

        System.out.println("调整结束:start:"+out.getNo()+" count:"+count);

        /**

         * 游戏开始

         */

        while(true){

            if(last==out){

                System.out.println(out.getNo()+"存活");

                break;

            }

            for (int i = 0; i < count; i++) {

                out=out.getNext();

                last=last.getNext();

            }

            System.out.println(out.getNo()+"出圈");

            out=out.getNext();

            last.setNext(out);

            System.out.println("start:"+out.getNo()+" count:"+count);

        }

    }

}

//主函数

public class Joswphu {
    public static void main(String[] args) {
        Linked l1 = new Linked();
        int n=8;
        l1.addtoLinked(n);
        l1.show();
        l1.JoswphuRolling(4, 2, n);
    }
}

 学习:B站尚硅谷公开视频

代码结合自己的理解和尚硅谷的代码进行改写

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿崽meitoufa

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

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

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

打赏作者

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

抵扣说明:

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

余额充值