约瑟夫问题升级版(密码问题)

题目:

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

题目分析:

首先是约瑟夫环的大小是变化的,因此相应的结点也是变化的,我们使用链式存储结构可以动态的生成其中的结点,删除操作也非常简单。用单向循环链表对其进行出列顺序比较合适。

解题步骤:

首先需要输入参与的人数;
输入第一个密码;
把第一个人定为头结点。

代码(java实现):

package DS02.动态链表;

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


public class JosephusLoopUpper {
    private Node head;//头结点
    private Node rear;//尾节点
    private int size;//数组大小
    private int M;//传入的第一个密码

    public JosephusLoopUpper(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++){//遍历所有人
            rear.next=new Node(list.get(i),i,rear.next);
            rear=rear.next;//添加人进链表
        }
        size=list.getSize();
        this.M=M;
    }
    public void out(){//删除人
        Node p=head;
        while(size>0){
            for(int i=1;i<=M-2;i++){
                p=p.next;
            }
            Node del=p.next;
            p.next=del.next;
            p=p.next;
            M=del.password;
            System.out.print(del.position+" ");
            size--;
        }

    }

    private class Node{
        int password;//密码
        int position;//位置
        Node next;//要删除的节点
        public Node(){}
        public Node(int password,int position, Node next){
            this.password=password;
            this.next=next;//链表的下一个节点
            this.position=position;
        }
    }

    public static void main(String[] args) {//测试
        //3 1 7 5 0 6 4 2
        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);
        JosephusLoopUpper ju=new JosephusLoopUpper(list,4);
        ju.out();
    }
}

发布了48 篇原创文章 · 获赞 47 · 访问量 5247

猜你喜欢

转载自blog.csdn.net/weixin_45160969/article/details/103639525