Java使用 单向循环链表实现约瑟夫问题

前奏
链表的特点:各个相依节点的地址空间不一定是连续的,这样就充分了历用了内存中的碎片内容存
约束夫小述
Josephus有过的故事:39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓。
于是决定了自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀。
然后下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,
Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏
单向循环链表实现代码
public class JosephDemo {
    public static void main(String[] args) {
        SingleLinekd2 singleLinekd2=new SingleLinekd2();

        for(int index=1;index<=41;index++){
            singleLinekd2.addNode(index);
        }
        //获取头节点
        MyNode node=singleLinekd2.headNode;
        MyNode temp=null;
        int countNumber=0;
        while(true){
            node=node.nextNode;
            countNumber++;

            //判断是否是第三个除数
            if(countNumber%3==0){
                System.out.println(node.obj.toString());
                singleLinekd2.deleteNode(node.obj);
                countNumber=0;
                if(singleLinekd2.isNull()){
                    break;
                }
            }
            //node=temp.nextNode;
        }
    }
}
class SingleLinekd2{
	
   
 public MyNode headNode=new MyNode();

    public boolean isNull(){
        return headNode.nextNode==null;
    }
    //添加节点
    public void addNode(Object obj){
        MyNode newNode=new MyNode(obj);
        MyNode currHeadNode=headNode;
        MyNode temp=null;

        while(currHeadNode.nextNode!=null){

            temp=currHeadNode.nextNode;
            if((Integer)temp.obj>(Integer)obj){
                break;
            }
            currHeadNode=temp;
            if(currHeadNode.nextNode==headNode.nextNode)break;
        }
        //当链表为空怎么处理
        if(currHeadNode.nextNode==null){
            newNode.nextNode=newNode;
            currHeadNode.nextNode=newNode;
        }
        //当位置为第一个的时候处理
        else if(currHeadNode==headNode){
            //获取最后一个节点
            MyNode lastNode=headNode;
            while(lastNode.nextNode!=null){
                lastNode=lastNode.nextNode;
                if(lastNode.nextNode==headNode.nextNode)break;
            }

            //更新最后一个节点信息
            lastNode.nextNode=newNode;

            newNode.nextNode=currHeadNode.nextNode;
            //更新头结点信息
            currHeadNode.nextNode =newNode;
        }else{
            newNode.nextNode=currHeadNode.nextNode;
            currHeadNode.nextNode=newNode;
        }
    }

    public void deleteNode(Object obj){
        MyNode currHeaNode=headNode;

        MyNode temp=null;
        while(currHeaNode.nextNode!=null){
            temp=currHeaNode.nextNode;

            if(temp.obj.equals(obj)){

                //判断当前节点是否是第一个
                if(temp==headNode.nextNode){

                   if(temp.nextNode==headNode.nextNode){
                       headNode.nextNode=null;
                       break;
                   }

                    //获取最后一个节点
                    MyNode lastNode=headNode;
                    while(lastNode.nextNode!=null){
                        lastNode=lastNode.nextNode;
                        if (lastNode.nextNode==headNode.nextNode)break;
                    }
                    //更新末尾节点信息
                    lastNode.nextNode=temp.nextNode;
                    headNode.nextNode=temp.nextNode;
                }
                else{
                    currHeaNode.nextNode=temp.nextNode;
                }
                break;
            }
            currHeaNode=temp;
            if(currHeaNode.nextNode==headNode.nextNode)break;
        }
    }


    //创建显示节点信息
    public void showNode(){

        //获取头节点
        MyNode currHeadNode=headNode;
        while(currHeadNode.nextNode!=null){
            System.out.println(currHeadNode.nextNode);

            currHeadNode=currHeadNode.nextNode;
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

}
结果:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值