约瑟夫环升级版

约瑟夫问题升级版


题目

  • 编号为1~N的N个人按顺时针方向围坐一圈,每个人持有一个密码(正整数,可以自由输入),开始人选一个正整数做为报数上限值M,从第一个人按顺时针方向自1开始顺序报数,报到M时停止报数。报M的人出列,将他的密码作为新的M值,从他顺时针方向上的下一个人开始从1报数,如此下去,直到所有人出列为止。

问题分析
和约瑟夫问题不同的是,升级版多了一个密码,这个密码可以从线性表导入,也就是在创建结点时,有三个区域密码域password、数据域位置position、指针域next。如下图所示

依旧是先初始化,再写游戏规则,在淘汰人时,依旧借助指针p遍历链表找到M位置的前一个,将指针域指向M处结点的下一个结点,即淘汰M处的结点,并将M的password作为新的M,继续上述步骤,直到全部淘汰。在游戏规则函数out中打印淘汰顺序。具体的在代码中有详细的注释。

代码实现


import DS01.动态数组.ArrayList;
//约瑟夫环升级版
public class Upper_JosephusLoop {

        private Node head;  //头指针
        private Node rear;  //尾指针
        private int size;   //未被淘汰的人数(相当于有效元素)
        private int M;      //报数的上限值

        public Upper_JosephusLoop(ArrayList<Integer> list,int M){
            head=new Node(list.get(0),0,null);      //先创建一个实结点,初始化让头尾指针都指向这个实结点
            rear=head;
            rear.next=head;             //尾指针的指针域指向头指针所在位置,构成循环链表
            for(int i=1;i<list.getSize();i++){
                //加结点 数据域从list里面拿,遍历的是位置,i给position结点的位置,指针域指向尾指针的下一个,也就是头
                rear.next=new Node(list.get(i),i,rear.next);
                rear=rear.next;         //更新尾指针
            }
            size=list.getSize();        //人数是list传进来的个数
            this.M=M;
        }
        //游戏淘汰函数
        public void out(){
            Node p=head;    //创建指针p,游戏是从头指针处开始
            while(size>0){
                for(int i=1;i<=M-2;i++){    //由当前位置跳到M的前一个结点
                    p=p.next;   //指针p移动
                }
                Node del=p.next;    //del存放要删除的结点
                p.next=del.next;    //p所在结点的指针域指向del的下一个结点(删除del,没人指向del,del被回收)
                p=p.next;           //更新指针p
                M=del.password;     //根据题意,M更新
                System.out.print(del.position+" ");   //返回删除了的结点的位置
                size--;     //有效元素个数-1
            }
        }

        //内部类
        private class Node{
            int password;   //数据域
            int position;   //位置
            Node next;  //指针域
            public Node(){}
            public Node(int password,int position,Node next){   //密码(数据域),位置,指针域
                this.password=password;
                this.position=position;
                this.next=next;
            }
        }

        public static void main(String[] args) {
            ArrayList<Integer> list=new ArrayList<>();	//创建顺序表对象
            list.addLast(3);		//表内从表尾进密码
            list.addLast(5);
            list.addLast(3);
            list.addLast(6);
            list.addLast(3);
            list.addLast(2);
            list.addLast(4);
            list.addLast(4);
            Upper_JosephusLoop ju=new Upper_JosephusLoop(list,4);	//M值初始给4
            ju.out();	//调用游戏规则函数
        }
    }

发布了70 篇原创文章 · 获赞 56 · 访问量 1978

猜你喜欢

转载自blog.csdn.net/qq_43624033/article/details/103634462