> 文档中心 > 单向环形链表应用场景(约瑟夫问题的讲解) java详细讲解

单向环形链表应用场景(约瑟夫问题的讲解) java详细讲解


单向环形链表应用场景

约瑟夫问题

单向环形链表应用场景(约瑟夫问题的讲解) java详细讲解
Josephu(约瑟夫、约瑟夫环) 问题

Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列

提示:用一个不带头结点的循环链表来处理Josephu 问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。

注:丢手帕问题

解题思路

1、新建一个环线链表,实现链表的增查功能
单向环形链表应用场景(约瑟夫问题的讲解) java详细讲解
2、设计出圈顺序,使用helper作为辅助指针,协助取消指针引用
单向环形链表应用场景(约瑟夫问题的讲解) java详细讲解

代码实现

package com.qf.linkedList;public class Josefu {    public static void main(String[] args) { CircleLinkedList circleLinkedList=new CircleLinkedList(); circleLinkedList.add(600); circleLinkedList.list(); circleLinkedList.countBoy(50,20,600);    }}class CircleLinkedList{    private Boy first=new Boy(-1);    //添加    public void add(int num){ if (num<1){     System.out.println("输入的数据有误,请重试~~~");     return; } Boy curBoy=null; for (int i = 1; i <= num; i++) {     Boy boy=new Boy(i);     if (i==1){  //第一个元素成为了队头,并循环  first=boy;  first.setNext(first);  curBoy=first;     }else{  boy.setNext(first);  curBoy.setNext(boy);  curBoy=boy;     } }    }    public void countBoy(int startNo,int countNums,int nums){ //从startNo开始数数 ,countNums表示的是步长,nums代表的是总共的长度 if (first==null||startNo<1||countNums>nums){     System.out.println("输入的数据有误,请重新输入"); } Boy helper=first; //1、找到helper的位置,它在first的前一个位置 while (true){     if (helper.getNext()==first){  break;     }     helper=helper.getNext(); } //2、让first、helper移动到指定的位置startNo,需要移动startNo-1下 for (int i=0;i<startNo-1;i++){     first=first.getNext();     helper=helper.getNext(); } //3、让小孩报数,移动first和helper的指针,移动countNums-1下 while (true){     if (first==helper){  break;     }     for (int j = 0; j < countNums-1; j++) {  first=first.getNext();  helper=helper.getNext();     }     System.out.println("出圈的编号为:"+first.getNo());     first = first.getNext();     helper.setNext(first); } System.out.println("组后出圈的编号为:"+first.getNo());    }    //展示    public void list(){ Boy temp=first; while (true){     System.out.println(temp);     if (temp.getNext()==first){  break;     }     temp=temp.getNext(); }    }}class Boy{    private int no;    private Boy next;    public Boy(int no){this.no=no;}    public int getNo() { return no;    }    public void setNo(int no) { this.no = no;    }    public Boy getNext() { return next;    }    public void setNext(Boy next) { this.next = next;    }    @Override    public String toString() { return "Boy{" +  "no=" + no +  '}';    }}

街头篮球