循环链表解决约瑟夫问题

循环链表解决约瑟夫问题

前言

传说有这样一个故事,在罗马人占领乔塔帕特后,39 个犹太人与约瑟夫及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,第一个人从1开始报数,依次往后,如果有人报数到3,那么这个人就必须自杀,然后再由他的下一个人重新从1开始报数,直到所有人都自杀身亡为止。然而约瑟夫和他的朋友并不想遵从。于是,约瑟夫要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,从而逃过了这场死亡游戏 。

一、循环链表

循环链表,顾名思义,链表整体要形成一个圆环状。在单向链表中,最后一个节点的指针为null,不指向任何结点,因为没有下一个元素了。要实现循环链表,我们只需要让单向链表的最后一个节点的指针指向头结点即可。
在这里插入图片描述

二、约瑟夫问题解决思路

根据前言可知,约瑟夫问题就是一个循环链表,我们只需要把每次自杀的人的位置编号打印出来,看最后是哪两个位置最后自杀,就可以让约瑟夫和它的朋友站在相应的位置,最后剩余他两,就可以逃之夭夭了,从此过上幸福美满的生活,十年之后…

  • 约瑟夫问题梳理
    41个人坐一圈,第一个人编号为1,第二个人编号为2,第n个人编号为n。
    1.编号为1的人开始从1报数,依次向后,报数为3的那个人退出圈;
    2.自退出那个人开始的下一个人再次从1开始报数,以此类推;
    3.求出最后退出的那个人的编号。

  • 代码实现

//约瑟夫问题
public class JosephTest {

    public static void main(String[] args) {
        //1. 创建循环链表
        Node<Integer> first=null; //第一个节点
        Node<Integer> curr=null; //当前节点
        for (int i=1;i<=41;i++)
        {
            //如果是第一个节点
            if(i==1)
            {
                first=new Node<>(i,null);
                curr=first;
                continue;
            }
            //如果是中间节点
            Node<Integer> newNode = new Node<>(i, null);
            curr.next=newNode;
            curr=newNode;
            //如果是最后一个节点
            if(i==41)
            {
                curr.next=first;
            }
        }

        //2. 遍历循环链表,完成自杀过程
        curr=first; //遍历的当前节点
        Node<Integer> curr_before=null; //当前节点的上一个节点
        int count = 0; //计算器,模拟第几个人报数
        //因为是循环链表,当一个节点的下一个节点是自己时(证明只是剩下一个人),则遍历结束
        while (curr!=curr.next)
        {
            count++;
            if(count==3)
            {
                //1.如果count等于3.打印并删除该节点,count重置为0
                System.out.print(curr.item+",");
                curr_before.next=curr.next;
                curr=curr.next;
                count=0;
            }
            else
            {
                //2.如果count不等于3,这移动当前节点
                curr_before=curr;
                curr=curr.next;
            }
        }
        //打印最后一个数
        System.out.print(curr.item);
    }

    private static class Node<T>
    {
        T item;
        Node next;
        public Node(T item, Node next)
        {
            this.item=item;
            this.next=next;
        }
    }
}
  • 运行结果
    在这里插入图片描述
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mekeater

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

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

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

打赏作者

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

抵扣说明:

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

余额充值